如何使用匹配、排序和限制对MongoDB聚合进行排序

如何使用匹配、排序和限制对MongoDB聚合进行排序,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我目前的汇总是: db.group_members.aggregate({ $match: { user_id: { $in: [1,2,3] } } }, { $group: { _id: "$group_id" } }, { $sort: { last_post_at: -1 } }, { $limit: 5 }) 对于以下文档结构: { _id: '...', user_id: '...', group_id: '...', last_post_at: D

我目前的汇总是:

db.group_members.aggregate({
  $match: { user_id: { $in: [1,2,3] } }
}, {
  $group: { _id: "$group_id" }
}, {
  $sort: { last_post_at: -1 }
}, {
  $limit: 5
})
对于以下文档结构:

{
  _id: '...',
  user_id: '...',
  group_id: '...',
  last_post_at: Date,
}
我还在
{user\u id:1,last\u post\u at:-1}

既然我的索引已经在上一篇文章上了,那么排序就没用了吗?我不能百分之百确定这个订单是怎么订的

我的最终目标是复制此SQL:

SELECT DISTINCT ON (group_id)
FROM group_members
WHERE user_id in [1,2,3]
ORDER_BY last_post_at DESC
LIMIT 5
我想知道如何使它对一个非常大的群体成员的表现,并仍然返回它在正确的顺序

更新:
我希望找到一个解决方案,限制加载到内存中的文档数量。这将是一个相当大的集合,访问非常频繁。

将$sort放在$group之前,否则MongoDB无法使用索引帮助排序


但是,在查询中,与组成员集合的总大小相比,您似乎希望查询相对较少的用户ID。因此,我建议只对用户id进行索引。在这种情况下,MongoDB将不得不按last_post_at对内存中的结果进行排序,但这是值得的,以交换使用索引进行用户id的初始查找。

您在$group阶段缺少分组操作-您希望last_post:{$max:$last_post_at}或者类似的东西。这是否仍然需要将用户id:{$in:[1,2,3]}的整个子集存储在内存中?组必须遍历所有匹配的文档-因为您的排序和限制基于聚合值,所以不能在组之前进行限制。可以想象,一种优化是可能的,它会在组之前对每个用户的id值进行排序和限制,但目前在2.4 MongoDB中没有实现。排序不是首先将整个集合加载到内存中吗?不,如果排序字段上有索引,则不会。如果您确实有这样一个索引,MongoDB将按照排序顺序迭代它。否则,它会尝试对内存中的所有内容进行排序,如果它使用了超过10%(我想)的RAM,它就会中止。我最终选择了第二个选项,经过一些基准测试后,它的速度比我预期的要快得多。