MongoDB - 基于非唯一字段的分页

Ada*_*uro 8 mongodb

我熟悉大型MongoDB集合中基于范围的分页的最佳实践,但是我正在努力弄清楚如何对排序值在非唯一字段上的集合进行分页.

例如,我有大量的用户,并且有一个字段表示他们做过某些事情的次数.此字段绝对不是唯一的,并且可能具有大量具有相同值的文档.

我想返回按'numTimesDoneSomething'字段排序的结果.

这是一个示例数据集:

{_id: ObjectId("50c480d81ff137e805000003"), numTimesDoneSomething: 12}
{_id: ObjectId("50c480d81ff137e805000005"), numTimesDoneSomething: 9}
{_id: ObjectId("50c480d81ff137e805000006"), numTimesDoneSomething: 7}
{_id: ObjectId("50c480d81ff137e805000007"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000002"), numTimesDoneSomething: 15}
{_id: ObjectId("50c480d81ff137e805000008"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000009"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000004"), numTimesDoneSomething: 12}
{_id: ObjectId("50c480d81ff137e805000010"), numTimesDoneSomething: 1}
{_id: ObjectId("50c480d81ff137e805000011"), numTimesDoneSomething: 1}
Run Code Online (Sandbox Code Playgroud)

如何返回按'numTimesDoneSomething'排序的数据集,每页有2条记录?

Sam*_*aye 5

@cubbuk使用offset(skip)显示了一个很好的例子,但你也可以模拟他为远程分页显示的查询:

db.collection.find().sort({numTimesDoneSomething:-1, _id:1})
Run Code Online (Sandbox Code Playgroud)

因为_id这里将是独一无二的,你是借调它实际上你可以再利用的范围_id和效果,即使两个记录之间具有numTimesDoneSomething12,应该是他们是否应该是一个页面或下一上是一致的.

所以做一些简单的事情

var q = db.collection.find({_id: {$gt: last_id}}).sort({numTimesDoneSomething:-1, _id:1}).limit(2)
Run Code Online (Sandbox Code Playgroud)

应该对远程分页工作相当好.

  • 很抱歉给这个答案留下来,但这不可能是正确的._id上的辅助排序并不排除具有*较旧*ID的文档在分页中*晚*.如果您只是查询$ gt最后一个ID,您将丢弃所有较旧的文档,这些文档可能具有较少的numTimes.为了实现这个目的,我相信你需要查询`$或:[{numtimes:last_numTimes,_id:last_id},{numTimes:{$ lt:last_numTimes}}`,原谅代码解释.如果我不对,请惩罚我.我正在努力解决目前我自己的非独特范围分页问题,​​并且正在寻找答案. (4认同)
  • @Sammaye 是的,但 _id 只是次要排序,并且仅在“numX”*相同*时影响顺序。结果很可能类似于“{numX: 2, _id: 2}, {numX: 2, _id: 3}, {numX: 1, _id: 1}”。在这种情况下,如果您的页面在第二个文档上结束,将导致“_id > 3”的“下一页”查询,这将抛出第三个结果。在真正的查询中,你会抛出更多。 (2认同)