在做$ cond

时间:2015-10-29 11:22:59

标签: mongodb mongodb-query aggregation-framework projection

我正在使用aggregationproject进行cond。像这样......

假设文件:

{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 level条件语句中收到错误:if(我尝试将if替换为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"}
       }
   }
}])

2 个答案:

答案 0 :(得分:1)

首先,您无法使用$exists,因为它仅在使用$match运算符或.find()方法的表达式中有效。尽管如此,您可以使用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"
            }

    }
}

答案 1 :(得分:0)

嗯......嗯......以及:

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

始终返回" null" for name.indexes

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

索引是:

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