MongoDB 分组+排序不起作用

Mic*_*zov 3 sorting mongodb aggregation-framework

我有这种情况。我收集了已发布的消息。消息可以共享(就像在 Facebook 上一样)。每次共享消息时,都会创建一条新消息,其中包含有关该消息是从哪条消息共享、哪条消息是原始消息以及内容可能会更改的信息。单个文档如下所示:

{
    "_id": <id>
    "source": <source_id>   // if it's original, own id is used
    "shared_from": <message_id>
    "trending": 4,
    "created": <Datetime>
}
Run Code Online (Sandbox Code Playgroud)

trending字段告诉我消息的“质量”。

现在,问题来了 - 我需要获得一些最好的消息。我还需要它们的来源是唯一的。这是我想出的,它应该有效(但事实并非如此)

db.Messages.aggregate({
    { $sort: { trending: -1 } },
    { $group: { _id: "$source", doc_id: { $first: "$_id" } } },
    { $project: { _id: "$doc_id" } },
    { $limit: 6 }
})
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我得到的结果完全混乱。它根本没有排序。这只是随机的。我错过了什么吗?

Asy*_*sky 5

您得到的结果未排序,因为您在该$group阶段之后没有对其进行排序。您已按趋势对事物进行排序,并在分组时利用这一点来确保只保留_id趋势分数最高的每种排序的值。但不能保证$group最终会保留任何特定的顺序,因此您应该再次排序,为此您需要保留趋势分数(假设您打算通过趋势分数降序来保持顺序)。

像这样的事情会起作用:

db.Messages.aggregate({
    { $sort: { trending: -1 } },
    { $group: { _id:"$source", doc_id:{$first: "$_id"}, trend:{$first:"$trending"}}},
    { $sort:{trend:-1} },
    { $project: { _id: "$doc_id" } },
    { $limit: 6 }
})
Run Code Online (Sandbox Code Playgroud)