簡體   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