在多进程环境下按插入顺序排序和限制MongoDB查询

8
我正在多进程环境中使用MongoDB,想知道如何按插入顺序排序查询,并将其限制为在某个文档之后插入的文档。在单进程中,我可以使用ObjectID,但是在不同进程中的两个ObjectIds可能会有错误的顺序。
示例:
ObjectId("5236dc5c 88ee6f 2075 bd0049")

可能是在2075进程之前生成的。
 ObjectId("5236dc5c 88ee6f 2071 f35fb8")

通过进程2071。注意两个ID的时间戳部分相等(5236dc5c)。此时间戳以秒为单位给出。


这种排序方式不可靠,因为你还会按照进程ID进行排序,而在这个示例中,这样做会破坏你的排序。最好是创建一个单独的日期类型字段来存储排序依据。 - Sammaye
2个回答

11
使用ObjectIds或日期字段进行排序可能无法得到您想要的结果。插入文档中的ObjectIds和日期是在客户端生成的,因此,如果您正在使用多台机器连接运行,则会遇到排序不一致性,除非您的机器之间的时间完全相同。
您能否提供更多有关您所尝试做的事情的详细信息?从MongoDB获取所需行为的方法有几种不同方式,具体取决于为什么需要一个特定文档之后插入的文档列表。
例如,如果您正在尝试将有序的文档列表用作某种队列,那么您可以使用findAndModify命令来获取未读文档并原子更新“read”字段,以确保您不会读取两次。每次调用findAndModify都会找到集合中最新的未设置为true的read字段的文档,原子地将该字段设置为true,并将您的文档返回给客户端进行处理。
另一方面,如果您的用例确实需要按插入顺序列出文档列表,则可以利用插入文档的自然排序。在MongoDB中,除非文档大小发生变化或删除需要移动,否则文档会按插入顺序写入磁盘。通过使用保证维护自然排序的封闭集合,您可以通过利用此功能获得文档列表。请注意,使用封闭集合有几个主要限制,您可以在文档中找到详细说明。

感谢您提供这么详细的答案。我需要实现一个跟踪系统状态变化的服务,以便客户端可以联系该服务来查询发生了什么变化。给定上一个“状态”的标识符(状态集合中条目的ObjectId),您希望能够检索此后发生的所有更改(状态集合中在具有给定ID的条目之后插入的所有文档)。我想到了使用固定大小集合来解决这个问题,尽管它会带来一些缺点,比如为每个用户创建一个状态集合。 - davidn

4
为了确保插入顺序,需要一个唯一的自增序列字段。有两种推荐的实现方式:
  1. 计数器集合
  2. 乐观循环
需要注意的一点是,文档没有说明:只有乐观循环确保插入顺序等于序列顺序。虽然计数器集合方法非常可能达到这个效果,但理论上无法保证,因为自增和文档插入是两个独立的操作。

这两个链接中的第一个不再涉及“计数器集合”之类的内容。此外,我还没有找到相应的文档,尽管我承认我不确定要查找什么。 - Ulrich Eckhardt
找到了:https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/ - Ulrich Eckhardt
谢谢提示。MongoDB文档已经更改。我更新了回复以包含有效的链接。 - davidn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接