0

我想要能夠執行聯合然後交集。MongoDB聯盟和一個通話中的交集

我的文檔strucuture:

{ 
    "_id" : 1, 
    "items" : [ 
     52711, 
     201610, 
     273342, 
     279449, 
     511250 
    ] 
}, 
{ 
    "_id" : 2, 
    "items" : [ 
     246421, 
     390200 
    ] 
} 

此集合包含的數以千計的上述形式的文獻。 我想在文檔集上執行聯合,然後在從聯盟返回的集合上執行交集。

例如:

Set 1 contains Id: [1,2,3,4,5] 
Set 2 Contains Id: [3,4,5,6,7,8] 
Set 3 Contains Id: [12,14,15,16,17] 

它應該在聯合組1中的所有列表中的項目,並設置2和組3然後在每一組的結果來執行相交。

db.getCollection('Test').aggregate([ 
    { "$match": { "_id": { "$in": [1, 2, 3] } } }, 
    { 
     "$group": { 
      "_id": 0, 
      "data": { "$push": "$items" } 
     } 
    }, 
    { 
     "$project": { 
      "items": { 
       "$reduce": { 
        "input": "$data", 
        "initialValue": [], 
        "in": { "$setUnion": ["$$value", "$$this"] } 
       } 
      } 
     } 
    } 
]) 

而且我做的這一切在C#現在:

,做清單的工會如下到目前爲止,我有查詢

var group = new BsonDocument 
        { 
         { "_id", 0 }, 
         { 
          "data", new BsonDocument {{"$push", "$items" } } 

         } 
      }; 


      var project = new BsonDocument 
      { 
       {"items", new BsonDocument 
        { 
         { "$reduce", new BsonDocument 
          { 
           { "input", "$data"}, 
           { "initialValue", new BsonArray()}, 
           { "in", new BsonDocument { {"$setUnion", new BsonArray { "$$value", "$$this" }}}} 
          } 
         } 
        } 
       } 
      }; 



      var result = qaCollection.Aggregate() 
       .Match(Builders<QAList>.Filter.In(x => x.Id, list)) 
       .Group(group) 
       .Project(project) 
       .FirstOrDefault(); 

這個查詢需要一定的時間,因爲它可能會返回大量數據。所以,如果我可以傳遞多個集合,並且它將聯合分離集合並相交,那麼它會非常好,所以數據不會很大。

在此先感謝..

回答

0

答案基礎上,answer given to question 24824361

沒有功能自動完成在幾個不同的文檔MongoDB中的交集。然而,可以採取這種方法來計算交點:

  1. 注意到你相交
  2. 放鬆項陣列
  3. 文件的數量計算每個項目的出現只是
  4. 比賽這些項目的出現次數與步驟1中的文檔數量相匹配

因此,例如,如果您正在交叉在3個文件中的項目,然後你解開項目,計數每個項目出現的次數,並完成僅出現3次的項目。

這隻會在每個文檔的items數組沒有重複時才起作用。

因此,例如,如果源數據是這樣的:

db.test_unionintersection_stackoverflow_42686348.insert([ 
    { "_id" : 1, 
    "items" : [ 10, 20, 30, 40, 50 ]}, 
    { "_id" : 2, 
    "items" : [ 20, 30, 40, 50, 60, 70, 80 ]}, 
    { "_id" : 3, 
    "items" : [ 10, 40, 50, 60, 80 ]}, 
    { "_id" : 4, 
    "items" : [ 20, 30, 40, 70, 80 ]} 
]) 

然後,如果你想要的文件1,2,3的交集(例如),你想要的結果[40, 50]

你可以這樣計算的話:

var document_ids = [1, 2, 3]; 
var number_documents = document_ids.length; 
db.test_unionintersection_stackoverflow_42686348.aggregate([ 
    { "$match": { "_id": { "$in": document_ids } } }, 
    { "$unwind": "$items"}, 
    { "$project" : { "_id" : 0, "item" : "$items"}}, 
    { "$group" : { _id: "$item", "count" : {$sum: 1}}}, 
    { "$match" : { "count" : number_documents}}, 
    { "$group" : { _id: "intersection", "items" : {$push: "$_id"}}}, 
]); 

它給你的結果:

{ 
    "_id" : "intersection", 
    "items" : [ 
     50.0, 
     40.0 
    ] 
}