Skip to main content
 首页 » 编程设计

mongodb之使用 $last 聚合并仅选择顶部记录

2024年02月23日21mq0036

我在 MongoDB 中有以下集合:

{ 
    "_id" : ObjectId("..."), 
    "assetId" : "...", 
    "date" : ISODate("..."), 
    ... 
} 

我需要做非常简单的事情 - 查找每个设备/ Assets 的最新记录。我有以下查询:

db.collection.aggregate([  
    { "$match" : { "assetId" : { "$in" : [ up_to_80_ids ]} } },  
    { "$group" :{ "_id" : "$assetId" , "date" : { "$last" : "$date"}}} 
]) 

整个表大约 20Gb。当我尝试执行此查询时,大约需要 8 秒,这没有任何意义,因为我指定只应选择 $last 记录。 assetId 和 date 均已编入索引。如果我在组之前添加 { $sort : { date : 1 } } ,它不会改变任何内容。

基本上,我的查询结果不应取决于数据大小。我唯一需要的是每个设备/ Assets 的最高记录。如果我执行 80 个单独的查询,则需要几毫秒的时间。

有什么方法可以让 MongoDB 不遍历整个表吗?看起来数据库并没有减少而是处理一切?!好吧,我知道这种行为应该有一些充分的理由,但我在文档或论坛上找不到任何内容。

更新:

最终找到了 2.4.6 解释查询的正确语法:

db.runCommand( { aggregate: "collection", pipeline : [...] , explain : true }) 

结果:

{ 
        "serverPipeline" : [ 
                { 
                        "query" : { 
                                "assetId" : { 
                                        "$in" : [ 
                                                "52744d5722f8cb9b4f94d321", 
                                                "52791fe322f8014b320dae41", 
                                                "52740f5222f8cb9b4f94d306", 
... must remove some because of SO limitations 
                                                "52744d1722f8cb9b4f94d31d", 
                                                "52744b1d22f8cb9b4f94d308", 
                                                "52744ccd22f8cb9b4f94d319" 
                                        ] 
                                } 
                        }, 
                        "projection" : { 
                                "assetId" : 1, 
                                "date" : 1, 
                                "_id" : 0 
                        }, 
                        "cursor" : { 
                                "cursor" : "BtreeCursor assetId_1 multi", 
                                "isMultiKey" : false, 
                                "n" : 960881, 
                                "nscannedObjects" : 960881, 
                                "nscanned" : 960894, 
                                "nscannedObjectsAllPlans" : 960881, 
                                "nscannedAllPlans" : 960894, 
                                "scanAndOrder" : false, 
                                "indexOnly" : false, 
                                "nYields" : 9, 
                                "nChunkSkips" : 0, 
                                "millis" : 6264, 
                                "indexBounds" : { 
                                        "assetId" : [ 
                                                [ 
                                                        "52740baa22f8cb9b4f94d2e8", 
                                                        "52740baa22f8cb9b4f94d2e8" 
                                                ], 
                                                [ 
                                                        "52740bed22f8cb9b4f94d2e9", 
                                                        "52740bed22f8cb9b4f94d2e9" 
                                                ], 
                                                [ 
                                                        "52740c3222f8cb9b4f94d2ea", 
                                                        "52740c3222f8cb9b4f94d2ea" 
                                                ], 
 
 
                                                .... 
 
 
                                                [ 
                                                        "5297770a22f82f9bdafce322", 
                                                        "5297770a22f82f9bdafce322" 
                                                ], 
                                                [ 
                                                        "529df5f622f82f9bdafce429", 
                                                        "529df5f622f82f9bdafce429" 
                                                ], 
                                                [ 
                                                        "529f6a6722f89deaabbf9881", 
                                                        "529f6a6722f89deaabbf9881" 
                                                ], 
                                                [ 
                                                        "52a6e35122f89ce6e2cf4267", 
                                                        "52a6e35122f89ce6e2cf4267" 
                                                ] 
                                        ] 
                                }, 
                                "allPlans" : [ 
                                        { 
                                                "cursor" : "BtreeCursor assetId_1 multi", 
                                                "n" : 960881, 
                                                "nscannedObjects" : 960881, 
                                                "nscanned" : 960894, 
                                                "indexBounds" : { 
                                                        "assetId" : [ 
                                                                [ 
                                                                        "52740baa22f8cb9b4f94d2e8", 
                                                                        "52740baa22f8cb9b4f94d2e8" 
                                                                ], 
                                                                [ 
                                                                        "52740bed22f8cb9b4f94d2e9", 
                                                                        "52740bed22f8cb9b4f94d2e9" 
                                                                ], 
                                                                [ 
                                                                        "52740c3222f8cb9b4f94d2ea", 
                                                                        "52740c3222f8cb9b4f94d2ea" 
                                                                ], 
 
                                                                ....... 
 
                                                                [ 
                                                                        "529df5f622f82f9bdafce429", 
                                                                        "529df5f622f82f9bdafce429" 
                                                                ], 
                                                                [ 
                                                                        "529f6a6722f89deaabbf9881", 
                                                                        "529f6a6722f89deaabbf9881" 
                                                                ], 
                                                                [ 
                                                                        "52a6e35122f89ce6e2cf4267", 
                                                                        "52a6e35122f89ce6e2cf4267" 
                                                                ] 
                                                        ] 
                                                } 
                                        } 
                                ], 
                                "oldPlan" : { 
                                        "cursor" : "BtreeCursor assetId_1 multi", 
                                        "indexBounds" : { 
                                                "assetId" : [ 
                                                        [ 
                                                                "52740baa22f8cb9b4f94d2e8", 
                                                                "52740baa22f8cb9b4f94d2e8" 
                                                        ], 
                                                        [ 
                                                                "52740bed22f8cb9b4f94d2e9", 
                                                                "52740bed22f8cb9b4f94d2e9" 
                                                        ], 
                                                        [ 
                                                                "52740c3222f8cb9b4f94d2ea", 
                                                                "52740c3222f8cb9b4f94d2ea" 
                                                        ], 
 
 
                                                        ........ 
 
 
                                                        [ 
                                                                "529df5f622f82f9bdafce429", 
                                                                "529df5f622f82f9bdafce429" 
                                                        ], 
                                                        [ 
                                                                "529f6a6722f89deaabbf9881", 
                                                                "529f6a6722f89deaabbf9881" 
                                                        ], 
                                                        [ 
                                                                "52a6e35122f89ce6e2cf4267", 
                                                                "52a6e35122f89ce6e2cf4267" 
                                                        ] 
                                                ] 
                                        } 
                                }, 
                                "server" : "351bcc56-1a25-61b7-a435-c14e06887015.local:27017" 
                        } 
                }, 
                { 
                        "$group" : { 
                                "_id" : "$assetId", 
                                "date" : { 
                                        "$last" : "$date" 
                                } 
                        } 
                } 
        ], 
        "ok" : 1 
} 

请您参考如下方法:

您的 explain 输出表明有 960,881 个项目与您的 $match 阶段中的 assetId 匹配。 MongoDB 使用 assetId 上的索引找到所有这些,并将它们全部流式传输到 $group 阶段。这很贵。目前MongoDB并没有对聚合管道进行太多的全管道优化,所以你所写的就是你所得到的,几乎是这样。

MongoDB 可以通过按 assetId 升序和日期降序排序来优化此管道,然后应用 SERVER-9507 中建议的优化。但这还没有实现。

目前,您最好的做法是对每个 assetId 执行此操作:

db.collection.find({assetId: THE_ID}).sort({date: -1}).limit(1)