3

MongoDB聚合在一分鐘內呈指數級複雜化!

我在$unwind嵌套數組,然後執行由的_id每個對象從unwinded嵌套數組。我的最後一次嘗試是通過$group反轉放回。但是,我無法重建具有原始屬性名稱的原始嵌入數組,以及每個文檔的原始直接屬性的其餘部分。

這是迄今爲止我嘗試:

db.users.aggregate([ 
    { 
     $unwind: "$profile", 
     $unwind: { 
      path: "$profile.universities", 
      preserveNullAndEmptyArrays: true 
     } 
    }, 
    { 
     $lookup: { 
      from: "universities", 
      localField: "profile.universities._id", 
      foreignField: "_id", 
      as: "profile.universities" 
     } 
    }, 
    { 
     $group: { 
      _id: "$_id", 
      emails: { "$first": "$emails" }, 
      profile: { "$first": "$profile" }, 
      universities: { "$push": "$profile.universities" } 
     } 
    } 
]).pretty() 

我得到的是這樣的:

{ 
    "_id" : "A_USER_ID", 
    "emails" : [ 
     { 
      "address" : "AN_EMAIL_ADDRESS", 
      "verified" : false 
     } 
    ], 
    "profile" : { 
     "name" : "NAME", 
     "company" : "A COMPANY", 
     "title" : "A TITLE", 
     "phone" : "123-123-1234", 
     "disabled" : false, 
     "universities" : [ 
      { 
       "_id" : "ID_1", 
       "name" : "UNIVERSITY_NAME_1", 
       "code" : "CODE_1", 
       "styles" : {AN_OBJECT} 
      } 
     ] 
    }, 
    "universities" : [ 
     [ 
      { 
       "_id" : "ID_1", 
       "name" : "UNIVERSITY_NAME_1", 
       "code" : "CODE_1", 
       "styles" : {AN_OBJECT} 
      } 
     ], 
     [ 
      { 
       "_id" : "ID_2", 
       "name" : "UNIVERSITY_NAME_2", 
       "code" : "CODE_2", 
       "styles" : {AN_OBJECT} 
      } 
     ] 
    ] 
} 

有2個問題,有這樣的結果:

  1. 產生的universities是每個對象都有一個數組的數組,因爲$lookup爲原始數據返回了一個元素數組$profile.universities嵌套數組。它應該只是一個對象數組。
  2. 由此產生的universities應該將其原始位置嵌套在profiles之下。我知道爲什麼原來的profile.universities是這樣的,因爲我使用的是$first運算符。我的意圖是保留profile的所有原始屬性,並保留原始嵌套的universities陣列。

最後,我需要的是這樣的:

{ 
    "_id" : "A_USER_ID", 
    "emails" : [ 
     { 
      "address" : "AN_EMAIL_ADDRESS", 
      "verified" : false 
     } 
    ], 
    "profile" : { 
     "name" : "NAME", 
     "company" : "A COMPANY", 
     "title" : "A TITLE", 
     "phone" : "123-123-1234", 
     "disabled" : false, 
     "universities" : [ 
      { 
       "_id" : "ID_1", 
       "name" : "UNIVERSITY_NAME_1", 
       "code" : "CODE_1", 
       "styles" : {AN_OBJECT} 
      }, 
      { 
       "_id" : "ID_2", 
       "name" : "UNIVERSITY_NAME_2", 
       "code" : "CODE_2", 
       "styles" : {AN_OBJECT} 
      } 
     ] 
    } 
} 

是否有另一家運營商,我可以用它代替$group實現這一目標?還是我錯誤地理解了$group的用途?

編輯:這是原來的職位,上下文: If Mongo $lookup is a left outer join, then how come it excludes non-matching documents?

回答

6

因爲$lookup運營商產生一個數組字段,你$group管道之前需要$unwind新領域得到想要的結果:

db.users.aggregate([ 
    { 
     "$unwind": "$profile", 
     "$unwind": { 
      "path": "$profile.universities", 
      "preserveNullAndEmptyArrays": true 
     } 
    }, 
    { 
     "$lookup": { 
      "from": "universities", 
      "localField": "profile.universities._id", 
      "foreignField": "_id", 
      "as": "universities" 
     } 
    }, 
    { "$unwind": "$universities" }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "emails": { "$first": "$emails" }, 
      "profile": { "$first": "$profile" }, 
      "universities": { "$push": "$universities" } 
     } 
    }, 
    { 
     "$project": { 
      "emails": 1, 
      "profile.name" : 1, 
      "profile.company": 1, 
      "profile.title" : 1, 
      "profile.phone" : 1, 
      "profile.disabled": 1,   
      "profile.universities": "$universities" 
     } 
    } 
]).pretty() 
+2

謝謝@chridam,se cond'$ unwind'和'$ project'完成了任務!我必須修改兩個部分:1.將第二個展開更改爲'「$ unwind」:{「path」:「$ profile.universities」,「preserveNullAndEmptyArrays」:true}',並且2.更改'$ group'「大學「轉到」大學「:{」$ push「:」$ profile.universities「},我能夠得到我的結果。 –