【问题标题】:Using MongoCollection.FindAll returns the same document twice使用 MongoCollection.FindAll 两次返回同一个文档
【发布时间】:2014-10-21 12:11:51
【问题描述】:

我们在系统中遇到了一个错误,该错误是由于从 MongoDB 获取重复文档而导致的。 当使用 FindAll 同时从另一个进程更新集合时会发生这种情况。

避免这种情况的最佳做法是什么?

我们不介意获取刚刚更新的文档的陈旧版本、获取刚刚删除的文档或丢失刚刚插入的文档。

我们已经看到游标有一个SetSnapshot 选项($snapshot: true),但对性能有何影响?为什么默认不开启?

我们可以手动删除返回的重复项,但这似乎不对,还会影响性能。


更新:

据我们了解,更改文档大小的更新可能会移动其在集合中的位置。如果在$snapshot选项关闭的情况下,在FindAll操作过程中发生这种更新,则文档可以返回两次。


更新 2:

在客户端(在内存中)手动删除重复项不是一种选择,因为某些文档可能会丢失(出于相同的原因,它们可能会出现两次)。

【问题讨论】:

    标签: mongodb mongodb-query mongodb-.net-driver


    【解决方案1】:

    对此有一个FAQ entry,它基本上说您可以通过以下任一方式防止重复的文档出现在您的查询中:

    • 使用$snapshot,但这不能用于分片集合或sort()
    • 根据不变且具有唯一索引的字段对查询进行排序

    因此,如果它的限制不会给您带来问题,请使用$snapshot,或者在静态、唯一索引字段(如_id)上对结果进行排序,必要时使用hint() 以确保它被使用。使用explain() 进行一些分析以测试您的选择。

    $snapshot 默认不启用,因为它的限制。

    【讨论】:

    • 谢谢,我们已经看到了这个常见问题解答,但这是要走的路吗?它会比无查询的查找引起更多的查找吗?如果是这样的话,找到后删除内存中的重复项会更好吗?
    • 是的,这是要走的路。在客户端删除重复项可能会更慢,而且肯定更混乱。
    • 删除重复的客户端是不可能的 - 一些现有的文档可能根本不会返回。你知道$snapshot 选项是否会对性能产生负面影响吗?再次感谢您的帮助:)
    • 我不确定您在最后一条评论中的意思。客户端我的意思是在查找后删除内存中的重复项。
    • 对不清楚的评论和快速编辑感到抱歉。我的意思是,经过一些测试,我们发现更新后的文档可能会返回两次,或者根本不会返回。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 2021-05-12
    • 1970-01-01
    • 2021-12-26
    • 2019-05-01
    • 1970-01-01
    • 2021-01-05
    相关资源
    最近更新 更多