繁体   English   中英

Mongodb 中的不相交集

[英]Disjoint sets in Mongodb

您好,有一个matchedpairs集合匹配对,其数据结构如下:

每个文档都定义了彼此之间的成对连接,即 1 与 2 联合,2 与 10 联合等。定义了大量的关系。

{
    x:1,
    y:2
},
{
    x:2,
    y:10
},
{
    x:9,
    y:10
},
{
    x:8,
    y:4
}

我想查询文档并检索对的唯一不相交集,即返回这样的结果

{
    set:[1,2,9,10]
},
{
    set:[8,4]
}

我熟悉聚合框架,但看不到如何在$group阶段创建正确的累加器来创建不相交的集合。 下面的尝试只是给出了一组相似的配对。 正如我所看到的,我必须创建一整串 $group 阶段(取决于我的数据集)才能获得我正在寻找的结果。 这里有什么聪明的主意吗?

db.matchedpairs.aggregate([
    {
        '$group': {
            '_id': '$y', 
            'like': {
                '$addToSet': '$x'
            }, 
            'from': {
                '$addToSet': '$y'
            }
        }
    }, {
        '$project': {
            '_id': 0, 
            'set': {
                '$setUnion': [
                    '$like', '$from'
                ]
            }
        }
    }
]

给出:

{
 set:[4,8]
},
{
 set:[10,2,9]
},
{
 set:[1,2]
}

也许将它转换为数组和 mapreduce 或自定义脚本会是有益的

db.matchedpairs.aggregate([
{ $project:{'set':['$x','$y']}},
{
        '$group': {
            '_id': '1', 
            'list': {
                '$addToSet': '$set'
            }
        }
},
{
  $out:'matchedpairs2'
}
]);


//gives => matchedpairs2

{
    "_id" : "1",
    "list" : [ 
        [ 
            1, 
            2
        ], 
        [ 
            9, 
            10
        ], 
        [ 
            2, 
            10
        ], 
        [ 
            8, 
            4
        ]
    ]
}
var map = function() {
  emit("list", this.list);
};

var emit = function(key, value) {
  const result = [];
  const result2 = [];

  value.map((item, i) => {
    const distinct = value.filter((w, j) => i != j);
    const convertset = [...new Set([].concat(...distinct))];
    const b = new Set(convertset);
    const intersection = item.filter(x => b.has(x));
    const diff = item.filter(x => !b.has(x));
    if (intersection.length > 0) result.push(item);
    if (diff.length > 0) result2.push(item);
  });

  const set1 = [...new Set([].concat(...result))];
  const set2 = [...new Set([].concat(...result2))];
  const w = new Set(set1);
  const diff2 = set2.filter(x => !w.has(x));
  const finalset = [...new Set([].concat(...diff2))]

  print(set1);
  print(finalset);
};

var myCursor = db.matchedpairs2.find({});

while (myCursor.hasNext()) {
  var doc = myCursor.next();
  map.apply(doc);
}

结果:


/* 1 */
[
    9.0,
    10.0,
    1.0,
    2.0
]

/* 2 */
[
    8.0,
    4.0
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM