簡體   English   中英

如何在Mongo和Mongo聚合中找到文檔中的匹配項?

[英]How to find match in documents in Mongo and Mongo aggregation?

我在mongo collection中有以下json結構-

 {
    "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"
}

我需要使用mongo聚合還是可以不使用聚合而獲得高於給定輸出的結果???

您在這里真正要問的是如何使MongoDB返回實際上不同於將其存儲在集合中的形式的東西。 標准查詢操作的確允許采用“限制”形式的“投影” ,但是,即使該鏈接中共享頁面上的標題表明,這實際上僅是基於根據“內容”中的內容“限制”要顯示在結果中的字段。您的文檔已經。

因此,任何形式的“替代”都需要某種形式的聚合,通過聚合和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"
  }},
])

因此,如果您想實質上“改變”輸出的結構,則需要使用一種聚合工具來完成。 即使您並未真正匯總任何內容,也可以。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM