MongoDB:结合聚合组进行排序
我有一个名为“交易”的集合,包含以下文档MongoDB:结合聚合组进行排序,mongodb,sorting,Mongodb,Sorting,我有一个名为“交易”的集合,包含以下文档 /* 0 */ { "_id" : ObjectId("5603fad216e90d53d6795131"), "statusId" : "65c719e6727d", "relatedWith" : "65c719e67267", "status" : "A", "userId" : "100", "createdTs" : ISODate("2015-09-24T13:15:36.609Z") } /
/* 0 */
{
"_id" : ObjectId("5603fad216e90d53d6795131"),
"statusId" : "65c719e6727d",
"relatedWith" : "65c719e67267",
"status" : "A",
"userId" : "100",
"createdTs" : ISODate("2015-09-24T13:15:36.609Z")
}
/* 1 */
{
"_id" : ObjectId("5603fad216e90d53d6795134"),
"statusId" : "65c719e6727d",
"relatedWith" : "65c719e6726d",
"status" : "B",
"userId" : "100",
"createdTs" : ISODate("2015-09-24T13:14:31.609Z")
}
/* 2 */
{
"_id" : ObjectId("5603fad216e90d53d679512e"),
"statusId" : "65c719e6727d",
"relatedWith" : "65c719e6726d",
"status" : "C",
"userId" : "100",
"createdTs" : ISODate("2015-09-24T13:13:36.609Z")
}
/* 3 */
{
"_id" : ObjectId("5603fad216e90d53d6795132"),
"statusId" : "65c719e6727d",
"relatedWith" : "65c719e6726d",
"status" : "D",
"userId" : "100",
"createdTs" : ISODate("2015-09-24T13:16:36.609Z")
}
当我运行下面的查询时
我按预期的排序顺序得到结果。i、 e按降序对创建的数据进行排序(最小结果)
如果我将下面的聚合应用于,则结果将被反向排序(即升序排序)
我以相反的顺序得到结果,即.*Sort createdTs以升序**
/* 0 */
{
"result" : [
{
"_id" : ObjectId("5603fad216e90d53d679512e"),
"createdTs" : ISODate("2015-09-24T13:13:36.609Z")
},
{
"_id" : ObjectId("5603fad216e90d53d6795134"),
"createdTs" : ISODate("2015-09-24T13:14:31.609Z")
},
{
"_id" : ObjectId("5603fad216e90d53d6795131"),
"createdTs" : ISODate("2015-09-24T13:15:36.609Z")
},
{
"_id" : ObjectId("5603fad216e90d53d6795132"),
"createdTs" : ISODate("2015-09-24T13:16:36.609Z")
}
],
"ok" : 1
}
我错在哪里?$group阶段不能确保结果的顺序。见第一段。 如果希望在$group之后对结果进行排序,则需要在$group阶段之后添加$sort 在您的情况下,您应该将$sort移动到$group之后,然后再提出以下问题:$sort不能像在$group之前那样在$group之后使用索引:-)
$group的内部算法似乎保留了某种排序(显然是相反的),但我不会指望这一点并添加$sort。您在这里没有做错任何事情,这是Mongodb中的$group行为 让我们看看这个例子 假设集合中有以下文档
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
现在如果你运行这个
db.collection.aggregate([{ $sort: { item: 1,date:1}} ] )
输出将按项目和日期的升序排列
现在,如果您在聚合管道中添加组阶段,它将颠倒顺序
db.collection.aggregate([{ $sort: { item: 1,date:1}},{$group:{_id:"$item"}} ] )
输出将是
{ "_id" : "xyz" }
{ "_id" : "jkl" }
{ "_id" : "abc" }
现在是你问题的解决方案
将组的“createdTs”:-1改为“createdTs”:1您可以尝试使用“createdTs”:1和测试吗MongoDB文档说明$group不会为任何订单投保。这个解决方案在将来的版本中可能不起作用,而且除了使查询看起来是错误的之外,还有点危险,因为现在它看起来与您真正想要做的相反。
db.collection.aggregate([{ $sort: { item: 1,date:1}} ] )
db.collection.aggregate([{ $sort: { item: 1,date:1}},{$group:{_id:"$item"}} ] )
{ "_id" : "xyz" }
{ "_id" : "jkl" }
{ "_id" : "abc" }