Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Node.js中优化组合MongoDB查询_Javascript_Node.js_Mongodb_Aggregation Framework - Fatal编程技术网

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
时,我可以看到此查询必须在执行期间扫描整个数据库。