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
VSunwind->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我已更新了答案,请再次检查