Javascript 在Node.js中优化组合MongoDB查询
我在Javascript 在Node.js中优化组合MongoDB查询,javascript,node.js,mongodb,aggregation-framework,Javascript,Node.js,Mongodb,Aggregation Framework,我在站点集合中存储了十个站点:站点A,站点B,站点C,站点D,站点E,站点F,站点G,站点H,站点I,站点J 现在,为了创建所有可能的车站对之间的所有车站间乘车的计数列表,我在Node.js代码中执行以下操作(使用Mongoose): const stationcompositions=[] //从stations集合获取所有电台 const stationIds=wait Station.find({},'.\u id name').lean().exec() //所有可能的从和到组合及其名称
站点集合中存储了十个站点:站点A
,站点B
,站点C
,站点D
,站点E
,站点F
,站点G
,站点H
,站点I
,站点J
现在,为了创建所有可能的车站对之间的所有车站间乘车的计数列表,我在Node.js代码中执行以下操作(使用Mongoose):
const stationcompositions=[]
//从stations集合获取所有电台
const stationIds=wait Station.find({},'.\u id name').lean().exec()
//所有可能的从和到组合及其名称的列表
stationId.forEach(fromStation=>{
StationId.forEach(toStation=>{
StationCompositions.push({fromStation,toStation})
})
})
常量结果=[]
//通过所有站点组合进行循环
for(const Station车站组合车站组合){
//创建聚合查询承诺
const data=Ride.aggregate([
{
$match:{
测试:错误,
声明:“已完成”,
持续时间:{$gt:2},
fromStation:mongoose.Types.ObjectId(stationCombination.fromStation.\u id),
toStation:mongoose.Types.ObjectId(stationCombination.toStation.\u id)
}
},
{
$group:{
_id:null,
计数:{$sum:1}
}
},
{
$addFields:{
fromStation:stationCombination.fromStation.name,
toStation:stationCombination.toStation.name
}
}
])
//将承诺推送到阵列
结果。推送(数据)
}
//运行所有聚合查询
const stationData=等待承诺。全部(结果)
//展平嵌套/空数组并返回
返回站data.flat()
执行此函数将以以下格式显示结果:
[
{
“fromStation”:“Station A”,
“toStation”:“A站”,
“计数”:1196
},
{
“fromStation”:“Station A”,
“toStation”:“车站B”,
“计数”:1
},
{
“fromStation”:“Station A”,
“toStation”:“C站”,
“计数”:173
},
]
对于所有其他组合,依此类推。。。
查询目前需要花费大量时间来执行,我不断从MongoDB Atlas收到关于由于这些查询导致数据库服务器负载过大的警报。当然,必须有一种优化的方法来执行类似的操作?您需要使用MongoDB本机操作。您需要通过fromStation
和toStation
和$lookup
加入两个集合
注意:我假设您有MongoDB>=v3.6和站点。_id
是ObjectId
db.ride.aggregate([
{
$match: {
test: false,
state: "completed",
duration: {
$gt: 2
}
}
},
{
$group: {
_id: {
fromStation: "$fromStation",
toStation: "$toStation"
},
count: {
$sum: 1
}
}
},
{
$lookup: {
from: "station",
let: {
fromStation: "$_id.fromStation",
toStation: "$_id.toStation"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
[
"$$fromStation",
"$$toStation"
]
]
}
}
}
],
as: "tmp"
}
},
{
$project: {
_id: 0,
fromStation: {
$reduce: {
input: "$tmp",
initialValue: "",
in: {
$cond: [
{
$eq: [
"$_id.fromStation",
"$$this._id"
]
},
"$$this.name",
"$$value"
]
}
}
},
toStation: {
$reduce: {
input: "$tmp",
initialValue: "",
in: {
$cond: [
{
$eq: [
"$_id.toStation",
"$$this._id"
]
},
"$$this.name",
"$$value"
]
}
}
},
count: 1
}
},
{
$sort: {
fromStation: 1,
toStation: 1
}
}
])
未测试:
const data = Ride.aggregate([
{
$match: {
test: false,
state: 'completed',
duration: { $gt: 2 }
}
},
{
$group: {
_id: {
fromStation: "$fromStation",
toStation: "$toStation"
},
count: { $sum: 1 }
}
},
{
$lookup: {
from: "station",
let: {
fromStation: "$_id.fromStation",
toStation: "$_id.toStation"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
[
"$$fromStation",
"$$toStation"
]
]
}
}
}
],
as: "tmp"
}
},
{
$project: {
_id: 0,
fromStation: {
$reduce: {
input: "$tmp",
initialValue: "",
in: {
$cond: [
{
$eq: [
"$_id.fromStation",
"$$this._id"
]
},
"$$this.name",
"$$value"
]
}
}
},
toStation: {
$reduce: {
input: "$tmp",
initialValue: "",
in: {
$cond: [
{
$eq: [
"$_id.toStation",
"$$this._id"
]
},
"$$this.name",
"$$value"
]
}
}
},
count: 1
}
},
{
$sort: {
fromStation: 1,
toStation: 1
}
}
])
您建议为此查询添加哪些索引?在执行explain
时,我可以看到此查询必须在执行期间扫描整个数据库。