2017-01-16 74 views
2

例如,我在收集如果至少有一个元素匹配时如何聚合2个列表?

{ _id: 1, list: ["A", "B"] } 
{ _id: 2, list: ["C", "A"] } 
{ _id: 3, list: ["E", "F"] } 
{ _id: 4, list: ["E", "D"] } 
{ _id: 5, list: ["U", "I"] } 
{ _id: 6, list: ["D", "K"] } 

6项我会做一个查询,合并所有的名单至少有1个元素匹配的项目。所以结果将是:

{ _id: 7, list: ["A", "B", "C"] } 
{ _id: 8, list: ["E", "F", "D", "K"] } 

我是新来的MongoDB,所以任何人都可以帮助我这个查询吗?非常感谢。

+0

你使用什么环境,比如Node.js,Java或mongo shell? – Karlen

+0

@卡伦:哦,我想用mongo shell:D有什么建议吗,Karlen? – Blurie

回答

1

我发现这个解决方案几乎可以解决您的问题。

{ "_id" : "E", "matchedIds" : [ 6, 3, 4 ], "size" : 2 } 
{ "_id" : "A", "matchedIds" : [ 1, 2 ], "size" : 2 } 

matchedIds表示文档id -s它们具有list阵列中常见值:

db.lists.aggregate([ 
    {$unwind:"$list"}, 
    {$group:{_id:"$list", merged:{$addToSet:"$_id"}, size:{$sum:1}}}, 
    {$match:{size: {$gt: 1}}},  
    {$project:{_id: 1, merged:1, size: 1, merged1: "$merged"}},  
    {$unwind:"$merged"},  
    {$unwind:"$merged1"},  
    {$group:{_id:"$merged", letter:{$first:"$_id"}, size:{$sum: 1}, set: {$addToSet:"$merged1"}}},  
    {$sort:{size:1}},  
    {$group:{_id: "$letter", mergedIds:{$last:"$set"}, size:{$sum:1}}},  
    {$match: {size:{$gt:1}}} 
]) 

我在蒙戈壳,其给出以下输出测试此。

我觉得在上面的聚合中可以做一些优化,但最初我发现这个,会试着找其他方法。另外,您可以在聚合管道末端使用$lookup聚合,以将id -s与set的值匹配。我无法测试这个,因为我的mongo版本不支持$lookup。但是,如果你使用Node.js或其他东西,你可以在一些for循环中手动获取这些值。

{ "_id" : 1, "list" : [ "A", "B" ] } 
{ "_id" : 2, "list" : [ "C", "A" ] } 
{ "_id" : 3, "list" : [ "E", "F" ] } 
{ "_id" : 4, "list" : [ "E", "D" ] } 
{ "_id" : 5, "list" : [ "U", "I" ] } 
{ "_id" : 6, "list" : [ "D", "K" ] } 
{ "_id" : 7, "list" : [ "A", "L" ] } 

但这:

编辑

如果相交列出的每个列表的数量不超过3个

例如这将工作这种算法只会工作将不会:

{ "_id" : 1, "list" : [ "A", "B" ] } 
{ "_id" : 2, "list" : [ "C", "A" ] } 
{ "_id" : 3, "list" : [ "E", "F" ] } 
{ "_id" : 4, "list" : [ "E", "D" ] } 
{ "_id" : 5, "list" : [ "U", "I" ] } 
{ "_id" : 6, "list" : [ "D", "K" ] } 
{ "_id" : 7, "list" : [ "L", "K" ] } 

这里带有7,6,4,3的ID的列表具有交集,因此相交列表的数量是4,在这种情况下提供的算法将不起作用。它将工作只有交集的数量少于4对每个列表

最后通知

看来你不能这样做在蒙戈数据库层合并计算达到您想要的结果。如果您正在构建应用程序,那么在应用程序层中执行计算也会更好。

+0

当然,这个问题很具有挑战性,但请注意,这个解决方案仅适用于最多3个交叉点的情况,就像答案中提到的那样。 – Karlen

+0

是的,请注意:D谢谢您的详细解答。 – Blurie

+0

不客气! – Karlen

相关问题