我有这张桌子,我想过滤它的某些字段。该表如下所示:
/* 1 */
{
"_id" : ObjectId("5ce7db93db1ec10d08941d44"),
"name" : "john",
"age" : "22",
"group" : "A",
"nodes" : [
{
"name1" : "some_name1",
"status" : "completed"
}
]
}
/* 2 */
{
"_id" : ObjectId("5ce7e2fd726ed9434c32aaba"),
"name" : "mike",
"age" : "23",
"group" : "B",
"nodes" : [
{
"dev_name" : "some_name_dev1",
"status" : "not completed"
},
{
"dev_name" : "some_name_dev2",
"status" : "completed"
}
]
}
/* 3 */
{
"_id" : ObjectId("5ce7e36c726ed9434c32aabc"),
"name" : "anne",
"age" : "24",
"group" : "C",
"status" : "pending"
}
/* 4 */
{
"_id" : ObjectId("5ce7f05e726ed9434c32aabe"),
"name" : "jane",
"age" : "27",
"group" : "D",
"nodes" : [
{
"dev_name" : "some_name_dev6",
"status" : "not completed"
},
{
"dev_name" : "some_name_dev7"
}
]
}
我真正想要返回的是这个(如果nodes
不存在,则为带有“状态”的简单对象,如果存在nodes
,则为一个数组:>
/* 1 */
[{
"status" : "completed"
}]
/* 2 */
[{
"status" : "not completed"
},
{
"status" : "completed"
}]
/* 3 */
{
"status" : "pending"
}
/* 4 */
[{
"status" : "not completed"
}]
我这样做了:
db.getCollection('user').find(
{
$or: [
{
"status": { $ne:null }
},
{
"nodes.status":{ $exists: true }
}
]
},
{
'status': 1,
'nodes.status': 1,
'_id': 0
}
)
结果是这样,我有点卡住了:
/* 1 */
{
"nodes" : [
{
"status" : "completed"
}
]
}
/* 2 */
{
"nodes" : [
{
"status" : "not completed"
},
{
"status" : "completed"
}
]
}
/* 3 */
{
"status" : "pending"
}
/* 4 */
{
"nodes" : [
{
"status" : "not completed"
},
{}
]
}
我如何获得想要的东西(摆脱nodes
字段)?谢谢您的时间!
编辑:
db.getCollection('user').find(
{
$or: [
{
"status": { $ne:null }
},
{
"nodes.status":{ $exists: true }
}
]
},
{
'status': 1,
'nodes.status': 1,
'_id': 0
},
[ { "$project": { "status": { "$ifNull" : ["$nodes.status", ""] } } } ]
)
答案 0 :(得分:0)
使用{$project: <expression>}
可以更改退货文件的格式,这是正确的方向。但是我认为$ifNull
的使用不正确。根据文档,$ifNull
的输入为
{ $ifNull: [ <expression>, <replacement-expression-if-null> ] }
完整查询:
db.getCollection('user').find(
{
$or: [
{
"status": { $ne:null }
},
{
"nodes.status":{ $exists: true }
}
]
},
{
'status': { "$ifNull" : ["$status", "$nodes.status"] },
'_id': 0
})
编辑:使用聚合而不是简单的find(),因为$ ifNull运算符仅在聚合中可用。
db.collection.aggregate([
{
$match: { #behaves like the find operator
$or: [
{
"status": {
$ne: null
}
},
{
"nodes.status": {
$exists: true
}
}
]
}
},
{
$project: {
"status": {
"$ifNull": [
"$status",
"$nodes.status"
]
},
"_id": 0
}
}
])
输出:
[
{
"status": [
"completed"
]
},
{
"status": [
"not completed",
"completed"
]
},
{
"status": "pending"
},
{
"status": [
"not completed"
]
}
]