这是一个技术性能问题:
我有一个这样的查询
db.collection.aggregate([
{$match:{...}},
{$group:{...}},
{$group:{...}},
{$project:{...}},
{$sort:...}
])
但如果我想设置限制,我使用$limit
在查询结束
db.collection.aggregate([
{$match:{...}},
{$group:{...}},
{$group:{...}},
{$project:{...}},
{$sort:...},
{$limit : 10}
])
所以我的问题是关于什么是放置$limit的最好方法:
- 咨询开始时。
- 会诊结束时
- 在咨询的任何部分:顺序不重要。
我的逻辑/头脑说You should to use "$limit" after $match to limit first results because maybe Mongo execute first $match and after will get result to process the next query's($group, $group, $project, $sort, ...)
。
p。S:我刚开始使用蒙古包。对不起,我的英语不好。
那么为什么$limit
在您提出的管道中是最后一个?:
db.collection.aggregate([
{"$match":{...}},
{"$group":{...}},
{"$group":{...}},
{"$project":{...}},
{"$sort":...},
{"$limit": 10}
])
因为正是应该做的。
所以在"管道"的"末端"是只返回"最后10个结果"的地方。
这与游标修饰符不同,操作是"顺序"发生的,所以"limit"发生在实现它的阶段之后。
因此:db.collection.aggregate([
{ "$limit": 10 },
{ .. whatever .. }
])
基本上是通过只查看集合中检索到的最"前"10个文档来控制的,没有任何其他条件,无论管道在其余阶段中说了什么。
Pipeline是一个"管道"。想想"Unix Pipe |
":
grep | sed | awk | sed | grep | awk
因为这正是所做的。你"输入"的就是你通过执行的操作"输出"的。
因此,每个管道阶段对其执行的顺序都很重要。这个地方是有用途的,不能互换。
当使用$limit
时,这真的取决于细节。然而,最好尽快使用$limit
,但顺序通常很重要。在不太可能的情况下,您只需要10个随机文档,那么您可以在$match
之后使用$limit
。但是,在您的情况下,您还使用$sort
,这将影响您希望返回的10个对象;因此,您应该在$sort
之后包含$limit
,除非您的聚合查询可以以一种您可以更早地使用排序和限制的方式进行优化。
db.collection.aggregate([
{ $match: { ... } },
// Will limit results exactly as they come, unsorted
{ $limit: 10 },
{ $group: {...}},
{ $group: {...}},
{ $project: {...}},
{ $sort: ...} // Will only sort the random 10
]);
db.collection.aggregate([
{ $match: { ... } },
{ $group: {...}},
{ $group: {...}},
{ $project: {...}},
{ $sort: ...}, // The sort likely matters, so limit after
{ $limit: 10 }
]);
然而,一个可以移动它的情况是,当你做排序的时候,你只是在按摩数据,这样可以在更少的数据下获得更高的性能:
db.collection.aggregate([
{ $match: { ... } },
{ $group: {...}},
{ $group: {...}},
{ $sort: ...},
{ $limit: 10 },
{ $project: {...}} // Since we only change the data format, it won't affect our limit
]);