我正在用project
和cond
做aggregation
。像这样的。。。
假设文件:
{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 } ]