2016-09-29 93 views
0

在收集test有文件如下的特定元素:查询嵌套数组或默认

{a:1, list:[{lang:"en", value:"Mother"}, {lang:"de", value:"Mutter"}] } 
{a:2, list:[{lang:"en", value:"Iddqd"}] } 

我想是尝试匹配list.value以所选语言生成的查询,但如果它不存在,则返回任何-服务现有的list项目,因此,例如上述和查询语言de我需要得到$projection为:

{a:1, label:"Mutter"}, 
{a:2, label:"Iddqd"} //since no label matched 'de' let's select any available 

Server版本:MongoDB的3.2+

+1

请您详细说明为什么您应该为第二个文档获得“{a:2,label:”Iddqd“}? – styvane

+0

列表的最大长度是否等于2? – styvane

+0

@Styvane - 刚刚更新,简称“Iddqd” - 是任何可用的项目。列表很短 - 不超过10 – Dewfy

回答

1

您需要过滤列表,使用$let运算符将结果赋值给变量。如果变量是空列表,则使用$arrayElemAt运算符返回给定值。在这种情况下,我只是返回第一个子文档。

db.coll.aggregate([ 
    { "$project": { 
     "a": 1, 
     "label": { 
      "$let": { 
       "vars": { 
        "values": { 
         "$arrayElemAt": [ 
          { "$filter": { 
           "input": "$list", 
           "as": "lst", 
           "cond": { "$eq": [ "$$lst.lang", "de" ] } 
          }}, 
          0 
         ] 
        } 
       }, 
       "in": { 
        "$ifNull": [ 
         "$$values.value", 
         { "$let": { 
          "vars": { 
           "default": { 
            "$arrayElemAt": [ "$list", 0 ] 
           } 
          }, 
          "in": "$$default.value" 
         }} 
        ] 
       } 
      } 
     } 
    }} 
]) 
+0

不知道为什么,但$ filter返回包含'de'和'en'的数组的两个项目 – Dewfy

+0

@Dewfy我更新了我的答案。有一点时间会增加更多的解释。 – styvane