"dotted field names are only allowed at the top level"做$cond时



我正在用projectcondaggregation。像这样的。。。

假设文件:

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

当我运行这个时,我在if条件语句上得到一个错误:exception: dotted field names are only allowed at the top level(我尝试用if:true替换if,聚合工作正常)。

这是个虫子吗?有没有一种不做其他项目的变通方法,只需让字段不带点就可以使用?

编辑

所以我找到了一个变通方法,但仍然想看看这是否是预期的行为。解决方法是通过$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"}
       }
   }
}])

首先,不能使用$exists,因为它只在带有$match运算符的表达式中或在.find()方法中有效。也就是说,您可以在if条件中使用"点表示法",但需要在其前面加上第一个查询中缺少的$符号。此外,您不能将文本对象键/值对作为或表达式的值返回,因为它不是有效的聚合表达式,您需要使用"点表示法"。

现在,正如您所提到的,一种方法是使用$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"
            }
    }
}

hmmm。。。。通过这个:

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

名称索引总是返回"null"

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

其中索引为:

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

相关内容

最新更新