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 
    ] 
}