在一个聚合查询中使用$sort
和$group
表现得很奇怪。
测试数据:
db.createCollection("test");
db.test.insert({
ts : 100,
category : 1
});
db.test.insert({
ts : 80,
category : 1
});
db.test.insert({
ts : 60,
category : 2
});
db.test.insert({
ts : 40,
category : 3
});
因此,当按ts
对其进行排序时,一切看起来都不错,但是当我同时使用$sort
和$group
时,结果的顺序错误。查询:
db.test.aggregate([
{
$sort : {ts: 1}
},
{
$group:{"_id":"$category"}
}
]);
结果顺序相反:
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
是Mongo功能还是我的误解? Maby mongo首先应用分组,然后无法按缺席字段排序。出于这个原因,mongoose
可能禁止使用distinct进行排序。
答案 0 :(得分:3)
您需要先$group
和$sort
结果。由于您只需要_id
字段,因此您需要$project
阶段。
db.test.aggregate(
[
{ "$group": { "_id": "$category" }},
{ "$sort" : { "ts": 1 }},
{ "$project": { "_id": 1 }}
]
);
答案 1 :(得分:0)
如果你想以另一种方式排序,可以这样做:
db.test.aggregate([
{
$sort : {ts: -1}
},
{
$group:{"_id":"$category"}
}
]);
注意1之前的-
。
答案 2 :(得分:0)
当您$sort
ts
时,您基本上是对您馆藏中的所有元素进行排序。因此,如果您只在聚合管道中运行$sort
阶段,您将得到以下结果:
//Query
db.test.aggregate([
{ $sort: { ts: 1} }
]);
//Output
{ "_id" : ObjectId("55141da6e4c260ae9e00832b"), "ts" : 40, "category" : 3 }
{ "_id" : ObjectId("55141d9fe4c260ae9e00832a"), "ts" : 60, "category" : 2 }
{ "_id" : ObjectId("55141d99e4c260ae9e008329"), "ts" : 80, "category" : 1 }
{ "_id" : ObjectId("55141d93e4c260ae9e008328"), "ts" : 100, "category" : 1 }
在您的代码中,当您添加$group
阶段时,您基本上是按category
字段对上述结果进行分组,从而产生您获得的输出:
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
最终,这一切都取决于你想要达到的目标。
如果要返回按ts
字段过滤的类别,则应仅使用$sort
阶段,然后操作结果数据集:
var data = db.test.aggregate([
{$sort: { ts: 1}},
{$project: {
_id: 0,
ts: 1,
category: 1
}
}
]).toArray();
for(var i = 0; i < data.length; i++) {
console.log(data[i].category); //Output 3, 2, 1 in that sequence, on different lines
}