MongoDB - 如何找到其他集合中未被文档引用的所有文档

Kor*_*son 6 mongodb

所以这是问题所在:

我在集合A中有文档,当它第一次创建时,它没有被任何其他文档引用.在某些时候,将创建集合Bwill中的文档,它将引用集合A中的文档的ObjectId.

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

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

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

感谢您的帮助和评论.

Ela*_*ava 8

使用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: []
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

上面的查询将返回集合a中没有集合引用的所有文档b.

不过要小心.性能可能会成为大型集合的问题.



Ian*_*cer 5

很多选择:

1)将B文档的id添加到A文档中的数组中(反向引用)。现在您可以查找在该数组中没有任何元素的 A 文档。问题:如果您有大量交叉引用,则数组对于文档大小来说可能会变得太大。

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

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

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

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

...