【问题标题】:How to find set intersection of sets between the documents in a single collection in MongoDB?如何在 MongoDB 的单个集合中查找文档之间的集合交集?
【发布时间】:2015-08-19 05:22:11
【问题描述】:

以下名为“coll”的集合在 mongodb 中维护。

{
    {"_id":1, "set":[1,2,3,4,5]},
    {"_id":2, "set":[0,2,6,4,5]},
    {"_id":3, "set":[1,2,5,10,22]}
}

如何找到上述集合文档中的集合元素与_id的1和3的交集。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    使用 aggregation framework 来获得所需的结果。可以发挥作用的聚合 set operator$setIntersection

    以下聚合管道可实现您的目标:

    db.test.aggregate([
        {
            "$match": {
                "_id": { "$in": [1, 3] }
            }
        },
        {
            "$group": {
                "_id": 0,
                "set1": { "$first": "$set" },
                "set2": { "$last": "$set" }
            }
        },
        {
            "$project": { 
                "set1": 1, 
                "set2": 1, 
                "commonToBoth": { "$setIntersection": [ "$set1", "$set2" ] }, 
                "_id": 0 
            }
        }
    ])
    

    输出

    /* 0 */
    {
        "result" : [ 
            {
                "set1" : [1,2,3,4,5],
                "set2" : [1,2,5,10,22],
                "commonToBoth" : [1,2,5]
            }
        ],
        "ok" : 1
    }
    

    更新

    要相交三个或更多文档,您需要 $reduce 运算符来展平数组。这将允许您与任意数量的数组相交,因此不仅仅是对文档 1 和 3 中的两个数组进行交集,这也适用于多个数组。

    考虑运行以下聚合操作:

    db.test.aggregate([
        { "$match": { "_id": { "$in": [1, 3] } } },
        {
            "$group": {
                "_id": 0,
                "sets": { "$push": "$set" },
                "initialSet": { "$first": "$set" }
            }
        },
        {
            "$project": {
                "commonSets": {
                    "$reduce": {
                        "input": "$sets",
                        "initialValue": "$initialSet",
                        "in": { "$setIntersection": ["$$value", "$$this"] }
                    }
                }
            }
        }
    ])
    

    【讨论】:

    • 你能解释一下在管道的小组阶段发生了什么,以及如果我们想在一个集合中的三个或四个文档之间执行交集,应该如何进行
    • 这仅在有正好两个文档要相交时才有效。如果有三个或更多,则不起作用(因为您不能再使用 $first 和 $last 分别投影数组)。
    • 恭喜您的回复!但我有以下问题:因为我想与所有文档相交,所以我得到BufBuilder attempted to grow() to 67108870 bytes, past the 64MB limit.,因为我的集合非常高:每个集合可能包含大约 600K 个 7 字节的元素。您是否有建议的解决方案或解决方法?提前谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多