所以,我有1000万人的文件。这个查询:
db.getCollection('people').find({'address.zip': '87447'}).sort({'name.last': -1}).limit(3)
返回< 20ms的
此查询:
db.getCollection('people').aggregate([{$match: {'address.zip': '87447'}},{$sort: {'name.last': -1}}, {$limit: 3}])
返回> 20S
我在address.zip
和name.last
只有大约100个符合$match
标准的文档...
...折流
这里有解释:
找到
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "people.people",
"indexFilterSet" : false,
"parsedQuery" : {
"address.zip" : {
"$eq" : "87447"
}
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"name.last" : -1.0
},
"limitAmount" : 3,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"address.zip" : 1
},
"indexName" : "address.zip_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"address.zip" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"address.zip" : [
"[\"87447\", \"87447\"]"
]
}
}
}
}
},
"rejectedPlans" : [
{
"stage" : "LIMIT",
"limitAmount" : 3,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"address.zip" : {
"$eq" : "87447"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name.last" : 1
},
"indexName" : "name.last_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name.last" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"name.last" : [
"[MaxKey, MinKey]"
]
}
}
}
}
]
},
"serverInfo" : {
"host" : "00caaca2f8e7",
"port" : 27017,
"version" : "3.7.2",
"gitVersion" : "ca0a855dfc0f479d85b76a640b12a259c0547310"
},
"ok" : 1.0
}
聚合
{
"stages" : [
{
"$cursor" : {
"query" : {
"address.zip" : "87447"
},
"sort" : {
"name.last" : -1
},
"limit" : NumberLong(3),
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "people.people",
"indexFilterSet" : false,
"parsedQuery" : {
"address.zip" : {
"$eq" : "87447"
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"address.zip" : {
"$eq" : "87447"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name.last" : 1
},
"indexName" : "name.last_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name.last" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"name.last" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : []
}
}
}
],
"ok" : 1.0
}
有关问题所在位置或如何解决问题的任何建议?
答案 0 :(得分:1)
聚合并查找使用不同的查询计划,因为当前聚合显式请求使用非阻塞计划(即可以使用索引提供排序顺序的计划)。
有一个Jira票证(https://jira.mongodb.org/browse/SERVER-7568)跟踪工作以改进这一点,因为如果少量文档与查询匹配,在内存中排序的查询计划会更快。
但是,在所有情况下,具有满足filter和sort子句的复合索引对于find和aggregate都会表现最佳。在您的情况下,这将是{"address.zip":1, "name.last":1}
请注意,从3.6开始,您还可以provide hint
to aggregate指定要使用的索引。
答案 1 :(得分:-1)
find()
方法用于在单个集合中查找数据作为您的条件。而当您需要使用一个或多个表执行aggregation
时使用joins()
。我并不是说您无法使用aggregation
,但如果您可以使用find()
获取数据,则无需使用aggregation
。如果您使用join()
在其他集合中拥有一些唯一键,也可以执行populate
。
profileModel.find({
_id: ObjectId("5a65dbba59d1d9128dd353b3")
})
.populate('pickupLocId').then((data) => {
res.send(data);
})