MongoDB聚合查询优化:匹配->;展开->;匹配与展开->;比赛

MongoDB聚合查询优化:匹配->;展开->;匹配与展开->;比赛,mongodb,mongoose,mongodb-query,aggregation-framework,aggregation,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,Aggregation,输入数据 { "_id" : ObjectId("5dc7ac6e720a2772c7b76671"), "idList" : [ { "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z", "displayId" : "H14", "currentQueue" : "10", "isRejected" : true,

输入数据

{
    "_id" : ObjectId("5dc7ac6e720a2772c7b76671"),
    "idList" : [ 
        {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : true
        },
        {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : false
        }
    ],
    "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f"),
    "processtype" : 1
}
{
    "_id" : ObjectId("5dc7ac6e720a2772c7b76671"),
    "idList":
     {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : true
    },
    "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f"),
    "processtype" : 1
}
输出数据

{
    "_id" : ObjectId("5dc7ac6e720a2772c7b76671"),
    "idList" : [ 
        {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : true
        },
        {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : false
        }
    ],
    "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f"),
    "processtype" : 1
}
{
    "_id" : ObjectId("5dc7ac6e720a2772c7b76671"),
    "idList":
     {
            "queueUpdateTimeStamp" : "2019-12-12T07:16:47.577Z",
            "displayId" : "H14",
            "currentQueue" : "10",
            "isRejected" : true,
            "isDispacthed" : true
    },
    "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f"),
    "processtype" : 1
}
查询1(
展开
然后
匹配

查询2(
匹配
然后
展开
然后
匹配

我的问题/我的担忧

(假设我在这个集合中有大量文档(50k+),并且假设我在同一管道中查询之后还有其他查找和预测)

match->unwind->match
VS
unwind->match

     aggregate([
     {
         $unwind: { path: "$idList" }
     },
     {
         $match: { 'idList.isDispacthed': isDispatched }
     }
     ])
     aggregate([
     {
         $match: { 'idList.isDispacthed': isDispatched }
     },
     {
         $unwind: { path: "$idList" }
     },
     {
         $match: { 'idList.isDispacthed': isDispatched }
     }
     ])
  • 这两个查询之间有性能差异吗
  • 有没有其他(更好的)方法来编写此查询

  • 这完全取决于MongoDB query planner优化器:

    聚合管道操作有一个优化阶段,该阶段尝试重塑管道以提高性能

    要查看优化器如何转换特定的聚合管道,请在db.collection.aggregate()方法中包含该选项

    poDetailsId
    创建索引并运行此查询:

    db.getCollection('collection').explain().aggregate([
         {
             $unwind: "$idList"
         },
          {
             $match: { 
               'idList.isDispacthed': true, 
               "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f") 
             }
         }  
    ])
    

    如您所见,MongoDB将此聚合更改为:

    db.getCollection('collection').aggregate([
         {
             $match: { "poDetailsId" : ObjectId("5dc7ac15720a2772c7b7666f") }
         }
         {
             $unwind: "$idList"
         },
         {
             $match: { 'idList.isDispacthed': true }
         }  
    ])
    
    从逻辑上讲,
    $match->$unwind->$match
    更好,因为您可以过滤(按索引)记录的子集,而不是完全扫描(处理100个匹配的文档)≠ 所有文件)

    如果聚合操作只需要集合中的数据子集,请使用
    $match
    $limit
    $skip
    阶段来限制在管道开头输入的文档。当放置在管道的开头时,
    $match
    操作使用合适的索引仅扫描集合中的匹配文档


    一旦您操作了文档,MongoDB就无法应用索引。
    聚合管道操作有一个优化阶段,它试图重塑管道以提高性能
    您能解释一下吗???请或者提供一个链接来理解这一点。这是否意味着
    diswind->match
    将变成
    match->diswind
    ??@kumarkundan执行以下操作:
    db.collection.explain().aggregate([…])
    它将显示MongoDB将执行何种聚合查询。@kumarkundan我已更新了答案,请再次检查