2015-10-29 38 views
1

我正在做aggregationprojectcond。事情是這樣的......

假設的文件:

{outter:{ 
    inner1:"blah", 
    innerOther:"somethingelse" 
}} 

聚合:

db.collection.aggregate([{ 
    $project : { 
     "outter.inner1":1, 
     "outter.inner2":{ 
      $cond : if:{"outter.innerOther":{$exists:true}}, 
        then:{"blah":"blah"}, 
        else:{"blah":"blah"} 
     } 
    } 
}]) 

當我運行此我得到一個錯誤:exception: dotted field names are only allowed at the top levelif條件語句(我試過更換如果與if:true和聚合工作)。

這是一個錯誤?有沒有做一個解決方法,而不是做一個完整的其他項目來簡單地讓字段沒有點?

編輯

所以,我發現了一個解決方法,但還是想看看這是預期的行爲。解決方法是通過$let在投影中使用變量。此外,看起來$exists不是有效的expression,所以不得不做出以下更改。

db.collection.aggregate([{ 
    $project : { 
     "outter.inner1":1, 
     "outter.inner2":{ 
      $let :{ 
       vars:{innerOther:{$ifNull:["$outter.innerOther", "absent"]}}, 
      } 
      $cond : if:{$eq:["$$innerOther","absent"]}, 
        then:{"blah":"blah"}, 
        else:{"blah":"blah"} 
     } 
    } 
}]) 
+0

是 「outter」 的陣列?請你能顯示你的文件嗎? – styvane

+0

Outter是一個子文檔。 –

回答

1

首先因爲它是唯一有效的表達與$match運營商或.find()方法中,你不能使用$exists。這就是說,您可以在if條件下使用"dot notation",但您需要在您的第一個查詢中缺少prefix it with the $ sign。此外,您無法將文字對象鍵/值對作爲值或表達式返回,因爲它不是有效的aggregation expressions,您需要使用"dot notation"代替。

現在,您提到的一種方法是使用$let操作和$project離子。當然,$ifNull條件運算符返回字段的當前值(如果它存在或替換表達式)。

db.collection.aggregate([ 
    { $project: { 
     "outter.inner1": 1, 
     "outter.inner2.blah": { 
      $let: { 
       vars: { 
        "outterinner2": { 
         $ifNull: [ "$outter.innerOther", "absent" ] 
        } 
       }, 
       in: { 
        $cond: [ 
         { $eq: [ "$$outterinner2", "absent" ] }, 
         "blah", 
         "blah" 
        ] 
       } 
      } 
     } 
    }} 
]) 

這樣做的另一種方式是使用兩個$project離子階段。

db.collection.aggregate([ 
    { $project: { 
     "inner1": "$outter.inner1", 
     "inner2": { 
      $ifNull: [ "$outter.innerOther", "absent" ] 
     } 
    }}, 
    { $project: { 
     "outter.inner1": "$inner1", 
     "outter.inner2.blah": { 
      $cond: [ 
       { $eq: ["$inner2", "absent"] }, 
       "blah", 
       "blah" 
      ] 
     } 
    }} 
]) 

兩個查詢得到這樣的事情:

{ 
     "_id" : ObjectId("5632713c8b13e9fb9cc474f2"), 
     "outter" : { 
       "inner1" : "blah", 
       "inner2" : { 
         "blah" : "blah" 
       } 
     } 
} 

編輯:

「點號」 是允許在$cond運營商。例如,以下查詢使用「點符號」。

db.collection.aggregate([ 
    { $project: { 
     "outter.inner1": 1, 
     "outter.inner2.blah": { 
      $cond: [ 
       { $eq: [ "$outter.innerOther", "somethingelse" ] }, 
       "anotherThing", 
       "nothing" 
      ] 
     } 
    }} 
]) 

和產量:

{ 
    "_id" : ObjectId("56379b020d97b83cd1506650"), 
    "outter" : { 
      "inner1" : "blah", 
      "inner2" : { 
        "blah" : "anotherThing" 
      } 

    } 
} 
0

嗯....和這樣的:

Model.aggregate([ 
        { 
         $project: { 
          name: 1, 
          "indexes.name":{ 
           $cond: { 
            if: {$eq:["$indexes.name",'стафилококки']}, 
            then: "$indexes.name", 
            else: null 
           } 
          }, 
          "indexes.units":1 
         } 
        } 
       ], callback) 

總是返回 「空」 的名稱。指標

[ 
    { _id: 564c6a5991b08dd017c2bd23, 
    name: ' воздух ', 
    indexes: [ [Object] ] }, 
    { _id: 564c6cf091b08dd017c2bd24, 
    name: 'repa ', 
    indexes: [ [Object] ] }, 
] 

其中指標爲:

[ { units: 'fvf', name: null } ] 
[ { units: 'КОЕ', name: null } ] 
+0

我已經研究過我的情況。它的令人難以置信的**,但$ cond中的「$ indexes.name」轉換爲array [「стафилококки」]!?儘管實際上它是一個像「單位」的字符串!**所以..沒有平等([「стафилококки」]!=「стафилококки」),而$ cond總是返回false,例如。空值 – meugen