2014-10-30 225 views
0

我有以下的蒙戈JSON結構收藏 -如何在Mongo和Mongo聚合的文檔中找到匹配?

{ 
    "students":[ 
     { 
     "name":"ABC", 
     "fee":1233 
     }, 
     { 
     "name":"PQR", 
     "fee":345 
     } 
    ], 
    "studentDept":[ 
     { 
     "name":"ABC", 
     "dept":"A" 
     }, 
     { 
     "name":"XYZ", 
     "dept":"X" 
     } 
    ] 
}, 
{ 
    "students":[ 
     { 
     "name":"XYZ", 
     "fee":133 
     }, 
     { 
     "name":"LMN", 
     "fee":56 
     } 
    ], 
    "studentDept":[ 
     { 
     "name":"XYZ", 
     "dept":"X" 
     }, 
     { 
     "name":"LMN", 
     "dept":"Y" 
     }, 
     { 
     "name":"ABC", 
     "dept":"P" 
     } 
    ] 
} 

現在我想要計算如下輸出。 如果students.name = studentDept.name 所以我的結果應該是如下

{ 
"name":"ABC", 
"fee":1233, 
"dept":"A", 
}, 
{ 
"name":"XYZ", 
"fee":133, 
"dept":"X" 
} 
{ 
"name":"LMN", 
"fee":56, 
"dept":"Y" 
} 

我需要使用蒙戈聚集或者是有可能得到上面給出的輸出,而無需使用聚合???

回答

0

你真的在這裏問的是如何讓MongoDB返回一些與你存儲它的形式完全不同的東西。標準查詢操作確實允許使用「限制」形式的"projection",但即使在該鏈接中共享的頁面上的標題暗示,這實際上只是關於根據文檔中的內容「限制」在結果中顯示的字段已經。

因此,任何形式的「變更」都​​需要某種形式的聚合,聚合和mapReduce操作都允許將文檔結果「重新塑形」爲與輸入不同的形式。也許人們對聚合框架尤其缺乏的主要是關於「聚合」的全部,實際上「重塑」概念是其實現的核心。

所以爲了得到結果,你怎麼想,你可以採取這樣的做法,應該在大多數情況下是合適的:

db.collection.aggregate([ 
    { "$unwind": "$students" }, 
    { "$unwind": "$studentDept" }, 
    { "$group": { 
     "_id": "$students.name", 
     "tfee": { "$first": "$students.fee" }, 
     "tdept": { 
      "$min": { 
       "$cond": [ 
        { "$eq": [ 
         "$students.name", 
         "$studentDept.name" 
        ]}, 
        "$studentDept.dept", 
        false 
       ] 
      } 
     } 
    }}, 
    { "$match": { "tdept": { "$ne": false } } }, 
    { "$sort": { "_id": 1 } }, 
    { "$project": { 
     "_id": 0, 
     "name": "$_id", 
     "fee": "$tfee", 
     "dept": "$tdept" 
    }} 
]) 

或者交替只是「過濾掉」的情況下,這兩個「名稱「字段不匹配,然後就項目與你想要的字段的內容,如果穿越文檔之間的內容是不是對你很重要:

db.collection.aggregate([ 
    { "$unwind": "$students" }, 
    { "$unwind": "$studentDept" }, 
    { "$project": { 
     "_id": 0, 
     "name": "$students.name", 
     "fee": "$students.fee", 
     "dept": "$studentDept.dept", 
     "same": { "$eq": [ "$students.name", "$studentDept.name" ] } 
    }}, 
    { "$match": { "same": true } }, 
    { "$project": { 
     "name": 1, 
     "fee": 1, 
     "dept": 1 
    }} 
]) 

從MongoDB的2.6及以上的,你甚至可以做同樣的事情」內聯「到兩個數組之間的文檔。你仍然想雖然重塑你的最終輸出數組的內容,但可以做的快一點:

db.collection.aggregate([ 

    // Compares entries in each array within the document 
    { "$project": { 
    "students": { 
     "$map": { 
     "input": "$students", 
     "as": "stu", 
     "in": { 
      "$setDifference": [ 
      { "$map": { 
       "input": "$studentDept", 
       "as": "dept", 
       "in": { 
       "$cond": [ 
        { "$eq": [ "$$stu.name", "$$dept.name" ] }, 
        { 
        "name": "$$stu.name", 
        "fee": "$$stu.fee", 
        "dept": "$$dept.dept" 
        }, 
        false 
       ] 
       } 
      }}, 
      [false] 
      ] 
     } 
     } 
    } 
    }}, 

    // Students is now an array of arrays. So unwind it twice 
    { "$unwind": "$students" }, 
    { "$unwind": "$students" }, 

    // Rename the fields and exclude 
    { "$project": { 
    "_id": 0, 
    "name": "$students.name", 
    "fee": "$students.fee", 
    "dept": "$students.dept" 
    }}, 
]) 

那麼,你想基本上是「改變」輸出的結構,那麼你需要使用的一個聚合工具來做。即使你沒有真正聚合任何東西,你也可以。