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)
当我这样做时,我得到的结果完全混乱。它根本没有排序。这只是随机的。我错过了什么吗?
您得到的结果未排序,因为您在该$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)