2017-01-16 72 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

相關問題