【问题标题】:Mongo aggregation framework, Sort and then group not workingMongodb聚合框架,排序然后分组不起作用
【发布时间】:2013-01-25 00:09:37
【问题描述】:

我正在尝试先按日期对数据进行排序,然后在另一个字段上分组。 它对我不起作用。

我要回答的问题是:选择最近的不同 cid?

鉴于此数据:

db.summary.save({"lid" : 5, "date" : 5, "cid" : 2, "circles" : [ 2 ] })
db.summary.save({"lid" : 2, "date" : 2, "cid" : 1, "circles" : [ 2 ] })
db.summary.save({"lid" : 4, "date" : 0, "cid" : 3, "circles" : [ 2 ] })
db.summary.save({"lid" : 3, "date" : 3, "cid" : 2, "circles" : [ 2 ] })
db.summary.save({"lid" : 1, "date" : 1, "cid" : 1, "circles" : [ 2 ] })

db.summary.aggregate( {$match :{circles: 2}, $sort: {date: -1}, $group: {_id: '$cid'}} )

我首先在圆圈上进行比赛, 然后是日期排序, 然后是cid上的一组

我得到的结果:

{
    "result" : [
        {
            "_id" : 3
        },
        {
            "_id" : 1
        },
        {
            "_id" : 2
        }
    ],
    "ok" : 1
}

这是我的分析:

在按日期匹配或排序之前,数据为:

"lid" : 5, "date" : 5, "cid" : 2
"lid" : 2, "date" : 2, "cid" : 1
"lid" : 4, "date" : 0, "cid" : 3
"lid" : 3, "date" : 3, "cid" : 2
"lid" : 1, "date" : 1, "cid" : 1

按日期排序后,数据集为:

"lid" : 5, "date" : 5, "cid" : 2
"lid" : 3, "date" : 3, "cid" : 2
"lid" : 2, "date" : 2, "cid" : 1 
"lid" : 1, "date" : 1, "cid" : 1
"lid" : 4, "date" : 0, "cid" : 3

所以分组后,我期望的结果是:

{
    "result" : [
        {
            "_id" : 2
        },
        {
            "_id" : 1
        },
        {
            "_id" : 3
        }
    ],
    "ok" : 1
}

什么查询可以解决我的问题?

为什么当前查询对我不起作用?

【问题讨论】:

  • aggregate 的管道参数需要放在数组中或作为独立对象而不是一个大对象传递。你的问题是关于在cid 上分组,但命令是在$date 上分组。
  • 那是一个错字。它应该是 $group: {_id: '$cid'}

标签: mongodb sorting aggregation-framework


【解决方案1】:

当您在管道中$sort 之后$group 时,先前的排序将丢失。您必须这样做,以便在分组后可以使用您想要排序的日期:

db.summary.aggregate(
    {$match: {circles: 2}},
    {$group: {_id: '$cid', date: {$max: '$date'}}},
    {$sort: {date: -1}});

结果:

[ { _id: 2, date: 5 }, 
  { _id: 1, date: 2 }, 
  { _id: 3, date: 0 } ]

如果您想重塑输出,请将$project 添加到管道的末尾。

【讨论】:

  • 谢谢!这正是我一直在寻找的,即使在你回答时我已经弄清楚了:)
  • 不要忘记,如果您想对 $group 中的任何内容进行排序,您必须将其包含在 $sort 中并带有 '_id.date'。检查stackoverflow.com/questions/21265170/…
  • “当你在管道中的 $sort 之后进行 $group 时,之前的排序会丢失。” 这不是真的(可能已经过时)。这不仅是可能的,而且是首选方式,因为这种方式排序可以使用索引:docs.mongodb.com/manual/reference/operator/aggregation/sort/…
  • @slouc 我的意思是,虽然 $group 的输入以 $sort 顺序接收其文档,但 $group 的输出顺序不会根据创建的 group doc 保持该顺序首先(这是 OP 所期望的)。
  • @JohnnyHK 是的,也许有误会。 Sort before group 将导致每个组内的排序项目,但组本身可以按任何顺序排列。我今天正在处理这个问题,你的陈述让我认为 $group 之前的 $sort 不会真正实现任何目标,这是不正确的(因为它确实会影响组内的项目排序)。
猜你喜欢
  • 1970-01-01
  • 2013-01-12
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多