use*_*181 12 mongodb aggregation-framework
我有两个系列
帖子:
{
"_Id": "1",
"_PostTypeId": "1",
"_AcceptedAnswerId": "192",
"_CreationDate": "2012-02-08T20:02:48.790",
"_Score": "10",
...
"_OwnerUserId": "6",
...
},
...
Run Code Online (Sandbox Code Playgroud)
和用户:
{
"_Id": "1",
"_Reputation": "101",
"_CreationDate": "2012-02-08T19:45:13.447",
"_DisplayName": "Geoff Dalgas",
...
"_AccountId": "2"
},
...
Run Code Online (Sandbox Code Playgroud)
我想找到写5到15个帖子的用户.这是我的查询的样子:
db.posts.aggregate([
{
$lookup: {
from: "users",
localField: "_OwnerUserId",
foreignField: "_AccountId",
as: "X"
}
},
{
$group: {
_id: "$X._AccountId",
posts: { $sum: 1 }
}
},
{
$match : {posts: {$gte: 5, $lte: 15}}
},
{
$sort: {posts: -1 }
},
{
$project : {posts: 1}
}
])
Run Code Online (Sandbox Code Playgroud)
它的工作速度很慢.对于6k用户和10k帖子,在关系数据库中获得响应需要40秒以上,我会在一瞬间获得响应.哪里出了问题?我刚刚开始使用mongodb,我很可能搞砸了这个查询.
bau*_*ace 16
来自https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
foreignField指定from集合中文档的字段.$ lookup在输入文档中对foreignField执行与localField的相等匹配.如果from集合中的文档不包含foreignField,则$ lookup将该值视为null以进行匹配.
这将与任何其他查询执行相同.
如果您在字段_AccountId上没有索引,它将为10,000个帖子中的每一个执行完整的表扫描查询.大部分时间将花在该表扫描中.
db.users.ensureIndex("_AccountId", 1)
Run Code Online (Sandbox Code Playgroud)
加快进程,因此它执行10,000次索引命中而不是10,000次表扫描.
除了bauman.space建议在_accountId字段上放置一个索引(这是关键的)之外,你还应该尽早在聚合管道中进行$ match阶段(即作为第一阶段).即使它不使用任何索引(除非您索引posts字段),它将在执行$ lookup(join)阶段之前过滤结果集.
您的查询非常慢的原因是,对于每个帖子,它都为每个用户执行非索引查找(顺序读取).那是大约60米的读数!
查看MongoDB聚合文档的管道优化部分.
| 归档时间: |
|
| 查看次数: |
13019 次 |
| 最近记录: |