嗯,这是一个技术性能问题:
我有这样的查询
db.collection.aggregate([
{$match:{...}},
{$group:{...}},
{$group:{...}},
{$project:{...}},
{$sort:...}
])
但如果我想要设置限制,我最后会在查询
上使用$limit
db.collection.aggregate([
{$match:{...}},
{$group:{...}},
{$group:{...}},
{$project:{...}},
{$sort:...},
{$limit : 10}
])
所以我的问题是关于什么是最好的限制因素:
我的逻辑/思想说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:我是使用Mongo的新手。抱歉我的英语不好。答案 0 :(得分:2)
那么为什么$limit
在你提议的管道中持续存在?:
db.collection.aggregate([
{"$match":{...}},
{"$group":{...}},
{"$group":{...}},
{"$project":{...}},
{"$sort":...},
{"$limit": 10}
])
因为完全它应该是什么。
因此,在“管道”的“结束”处,只返回“最后10个结果”。
这不像光标修饰符,操作“按顺序”发生,因此“限制”发生在它实现的阶段之后。
因此:
db.collection.aggregate([
{ "$limit": 10 },
{ .. whatever .. }
])
基本上仅通过查看集合中非常“第一”的10个文档进行控制,无需其他条件即可重新审阅,无论管道在剩余的阶段中如何说明。
管道是一个“管道”。想想“Unix管道|
”:
grep | sed | awk | sed | grep | awk
因为完全它的作用。你“喂”的是你通过所执行的操作“走出去”。
因此,每个流水线阶段对其执行顺序都很重要。这个地方有目的,不可互换。
答案 1 :(得分:1)
使用$limit
时,实际上取决于细节。但是,最好尽快使用$limit
,但订单通常很重要。如果您只需要10个随机文档,那么您可以在$limit
之后立即使用$match
。但是,在您的情况下,您还使用$sort
,这将影响您想要返回的10个对象;因此,您应该在$limit
之后添加$sort
,除非您的聚合查询可以通过以前可以使用排序和限制的方式进行优化。
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
]);