在MongoDB上执行聚合/设置交集



我有一个查询,在对样本数据集执行一些聚合后,将以下示例视为中间数据;

fileid字段包含文件的id,用户数组包含对相应文件进行了一些更改的用户数组

{
“_id” : {  “fileid” : 12  },
“_user” : [ “a”,”b”,”c”,”d” ]
}
{
“_id” : {  “fileid” : 13  },
“_user” : [ “f”,”e”,”a”,”b” ]
}
{
“_id” : {  “fileid” : 14  },
“_user” : [ “g”,”h”,”m”,”n” ]
}
{
“_id” : {  “fileid” : 15  },
“_user” : [ “o”,”r”,”s”,”v” ]
}
{
“_id” : {  “fileid” : 16  },
“_user” : [ “x”,”y”,”z”,”a” ]
}
{
“_id” : {  “fileid” : 17  },
“_user” : [ “g”,”r”,”s”,”n” ]
}

我需要找到解决方案->任何两个用户对同一文件中的至少两个进行了一些更改。所以输出结果应该是

{
“_id” : {  “fileid” : [12,13]  },
“_user” : [ “a”,”b”]
}
{
“_id” : {  "fileid” : [14,17]  },
“_user” : [ “g”,”n” ]
}
{
“_id” : {  "fileid” : [15,17]  },
“_user” : [ “r”,”s” ]
}

非常感谢您的意见。

这是一个有点复杂的解决方案。这个想法是首先使用DB来获得可能的配对的总体,然后回过头来要求DB在_user字段中找到配对。请注意,1000个用户将创建一个非常大的配对列表。我们使用$addFields只是为了防止输入记录比我们在示例中看到的更多,但如果没有,为了提高效率,请使用$project来减少流经管道的材料量。

//
// Stage 1:  Get unique set of username pairs.
//
c=db.foo.aggregate([
{$unwind: "$_user"}
// Create single deduped list of users:
,{$group: {_id:null, u: {$addToSet: "$_user"} }}
// Nice little double map here creates the pairs, effectively doing this:
//    for index in range(0, len(list)):
//      first = list[index]
//      for p2 in range(index+1, len(list)):
//        pairs.append([first,list[p2]])
// 
,{$addFields: {u: 
{$map: {
input: {$range:[0,{$size:"$u"}]},
as: "z",
in: {
$map: {
input: {$range:[{$add:[1,"$$z"]},{$size:"$u"}]},
as: "z2",
in: [
{$arrayElemAt:["$u","$$z"]},
{$arrayElemAt:["$u","$$z2"]}
]
}
}
}}
}}
// Turn the array of array of pairs in to a nice single array of pairs:
,{$addFields: {u: {$reduce:{
input: "$u",
initialValue:[],
in:{$concatArrays: [ "$$value", "$$this"]}
}}
}}
]);

// Stage 2:  Find pairs and tally up the fileids
doc = c.next(); // Get single output from Stage 1 above.                       
u = doc['u'];
c2=db.foo.aggregate([
{$addFields: {_x: {$map: {
input: u,
as: "z",
in: {
n: "$$z",
q: {$setIsSubset: [ "$$z", "$_user" ]}
}
}
}
}}
,{$unwind: "$_x"}
,{$match: {"_x.q": true}}
//  Nice use of grouping by an ARRAY here:
,{$group: {_id: "$_x.n", v: {$push: "$_id.fileid"}, n: {$sum:1} }}
,{$match: {"n": {"$gt":1}}}
]);
show(c2);

相关内容

  • 没有找到相关文章

最新更新