【问题标题】:MongoDB - how can I find all documents that aren't referenced by a document from another collectionMongoDB - 我如何找到另一个集合中的文档未引用的所有文档
【发布时间】:2012-05-29 13:50:38
【问题描述】:

所以问题来了:

我在集合 A 中有文档,当它第一次创建时,它没有被任何其他文档引用。在某个时候,集合 B 中的一个文档将被创建,并且它将引用集合 A 中文档的 ObjectId。

在集合 A 中查找集合 B 中的 I 文档未引用的所有文档的最佳方法是什么?

我了解 MongoDB 不支持连接,但我想知道除了从集合 B 中获取所有引用的 ObjectId 并在集合 A 中查找不在该列表中的文档之外,是否有解决此问题的方法,因为此解决方案可能不能很好地扩展。

我可以将集合 A 中的文档嵌入到集合 B 中的文档中,然后将其从集合 A 中删除吗?这是最好的解决方案吗?

感谢您的帮助和 cmets。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    在 MongoDB 3.2 中,添加 $lookup 运算符使这成为可能:

    db.a.aggregate(
    [
        {
            $lookup: {
                from: "b", <-- secondary collection name containing references to _id of 'a'
                localField: "_id",  <-- the _id field of the 'a' collection
                foreignField: "a_id", <-- the referencing field of the 'b' collection
                as: "references"
            }
        },
        {
            $match: {
                references: []
            }
        }
    ]);
    

    上述查询将返回集合a 中所有在集合b 中没有引用的文档。

    不过,请注意这一点。大型集合的性能可能会成为问题。


    【讨论】:

      【解决方案2】:

      很多选择:

      1) 将 B 文档的 id 添加到 A 文档中的数组中(反向引用)。现在您可以查找在该数组中没有任何元素的 A 文档。问题:如果您有很多交叉引用,数组可能会变得太大而无法满足文档大小。

      2) 添加一个集合 C,用于跟踪 A 和 B 之间的引用。表现得像一个连接表。

      3) 在 A 'referenced' 中有一个简单的标志。当您添加 B 时,将它引用的所有 A 标记为“已引用”。当您删除 B 时,请扫描 B 以查找它所引用的所有 A,并取消标记任何不再具有引用的 A。问题:可能不同步。

      4) 在 B 上使用 map reduce 创建一个集合,其中包含任何 B 引用的所有 A 的 id。使用该集合标记所有引用的 A(在首先取消标记所有它们之后)。可以使用它定期修复 (3)。

      5) 将两种文档类型放在同一个集合中,并使用 map reduce 发出 _id 和一个标志来表示“在 A 中”或“被 B 引用”。在减少步骤中,查找“在 A 中”但没有“被 B 引用”的任何组。

      ...

      【讨论】:

      • 谢谢,我想我将继续使用选项 1,因为我需要文档 B 与文档 A 相关的所有时间的历史记录...我还可以设置一个标志来指示何时如果文档 B 当前适用。
      【解决方案3】:

      由于没有连接,唯一的选择是您提到的那一次:要么使用嵌入式文档,要么让您自己使用两部分查询。

      这取决于您的实现,但是将文档类型 B 添加到 A 中的相应文档听起来是最好的选择。这样您就可以使用简单的查询 ($exists operator) 来检索没有 B 的 A...

      A.find( { B: { $exists: false } })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-19
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 2016-09-22
        • 2014-08-16
        • 2016-02-22
        相关资源
        最近更新 更多