简体   繁体   English

MongoDB 使用游标进行分页而不进行排序

[英]MongoDB pagination using cursors without sorting

When looking for pagination techniques on the internet, one usually finds two ways:在互联网上寻找分页技术时,通常会找到两种方法:

  • Offset-based pagination:基于偏移的分页:
Collection.find(
  { where_this: "equals that" },
  { skip: 15, limit: 5 }
) 
  • Cursor-based pagination:基于光标的分页:
Collection.find(
  { where_this: "equals that", _id: { $gt: cursor }},
  { sort: { _id: 1 }}
) 

But is there a way to have cursor-based pagination without sorting the collection according to that cursor?但是有没有办法在不根据 cursor 对集合进行排序的情况下进行基于光标的分页? Like, telling Mongo "Alright, I want the 5 next items after that _id , no matter in which order the _ids are, just give me 5 items after you see that _id ".比如,告诉 Mongo “好吧,我想要 _id 之后的 5 个下一个项目,无论_id的顺序是什么,只要在你看到那个_id后给我 5 个项目”。 Something along those lines:沿着这些思路:

Collection.find(
  { where_this: "equals that", _id: { $must_come_after: cursor }},
  { sort: { other_field: 1 }}
) 

It is not always possible to use the field you're sorting with as the cursor.并非总是可以将您排序的字段用作 cursor。 First of all, because these fields can be of different types and you might allow your app users to sort, for example, tables as they please.首先,因为这些字段可以是不同的类型,并且您可能允许您的应用程序用户随意排序,例如,表格。 With a strongly-typed API framework like GraphQL, this would be a mess to handle.对于像 GraphQL 这样的强类型 API 框架,这将是一团糟。 Secondly, you could have two or more equal values for that field following each other in the sorted collection.其次,您可以在已排序的集合中为该字段设置两个或多个相等的值。 If your pages split in the middle, asking for the next page will either give you duplicates or ignore items.如果您的页面在中间拆分,则要求下一页将给您重复或忽略项目。

Is there a way to do that?有没有办法做到这一点? How is it usually done to allow custom sorting fields without offset-based pagination?通常如何在没有基于偏移的分页的情况下允许自定义排序字段? Thanks.谢谢。

When we talk about "paginating a result set", the implicit assumption is that the result set stays the same throughout the process.当我们谈论“对结果集进行分页”时,隐含的假设是结果集在整个过程中保持不变。 In order for the result set to stay the same, it must normally be sorted.为了使结果集保持不变,通常必须对其进行排序。 Without specifying an order, the database is free to return the documents in any order, and this order may change from one retrieval to the next.在不指定顺序的情况下,数据库可以按任何顺序自由返回文档,并且此顺序可能会从一次检索更改为下一次检索。 Reordering of documents that a user is paginating through creates a poor user experience.对用户正在分页的文档进行重新排序会造成糟糕的用户体验。

you could have two or more equal values for that field following each other in the sorted collection.在已排序的集合中,您可以有两个或多个相同的字段值。 If your pages split in the middle, asking for the next page will either give you duplicates or ignore items.如果您的页面在中间拆分,则要求下一页将给您重复或忽略项目。

The database can return the documents which compare equal in any order, and this order can change between adjacent queries.数据库可以以任意顺序返回比较相等的文档,并且该顺序可以在相邻查询之间改变。 This is why when sorting on a field that has a low cardinality, it is a good idea to add another field with a high cardinality to the sort expression to ensure the documents are returned in a stable order.这就是为什么在对具有低基数的字段进行排序时,最好在排序表达式中添加另一个具有高基数的字段,以确保文档以稳定的顺序返回。

But is there a way to have cursor-based pagination without sorting the collection according to that cursor?但是有没有办法在不根据 cursor 对集合进行排序的情况下进行基于光标的分页?

You can encode offset in a cursor identifier and use skip/limit.您可以在 cursor 标识符中编码偏移量并使用跳过/限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM