我想过滤Categories
嵌入数组,只获得那些parent
密钥的数据。
{
"_id": ObjectId("5737283639533c000978ae71"),
"name": "Swiss",
"Categories": [
{
"name": "Management",
"_id": ObjectId("5738982e39533c00070f6a53")
},
{
"name": "Relations",
"_id": ObjectId("5738984a39533c000978ae72"),
"parent": ObjectId("5738982e39533c00070f6a53")
},
{
"name": "Ambiance",
"_id": ObjectId("57389bed39533c000b148164")
}
]
}
我已尝试使用find
,但没有成功。
经过一些研究后,它似乎可以通过聚合命令完成,但我不喜欢它的工作方式,我宁愿只使用find命令。
另外,我问自己,如果在表演方面,将每个类别存储在新系列中会不会更好,是不是?
编辑,我想得到像这样的东西:查找输出:
[
{
"name": "Relations",
"_id": ObjectId("5738984a39533c000978ae72"),
"parent": ObjectId("5738982e39533c00070f6a53")
}
]
答案 0 :(得分:1)
根据上述说明,请尝试执行以下查询
db.mycoll.find({Categories:{$elemMatch:{parent:{$exists:true}}}},
{Categories:{$elemMatch:{parent:{$exists:true}}}})
上面的示例使用$elemMatch运算符来过滤嵌入文档中的元素。
答案 1 :(得分:1)
最佳方法是使用聚合框架在MongoDB 3.2中。您只需要投影文档并使用$filter
运算符返回符合条件的“类别”数组的子集,但要执行此操作,您需要使用$ifNull
运算符给出“默认值” “缺少该字段的所有子文档中的”父“字段的值,然后使用cond
表达式中的$ne
来确定应该在子集中包含给定元素的位置。
db.collection.aggregate([
{ "$project" : {
"_id": 0,
"Categories": {
"$filter": {
"input": "$Categories",
"as": "catg",
"cond": {
"$ne": [
{ "$ifNull": [ "$$catg.parent", false ] },
false
]
}
}
}
}}
])
从版本3.0开始,您需要一种不同的方法。相反,您需要使用$map
运算符返回给定元素(如果它符合您的条件)或false
然后使用$setDifference
运算符过滤掉返回数组中相同的所有元素到false
。当然,只要被过滤的数据是“唯一的”,$setDifference
就可以了。
db.collection.aggregate([
{ "$project" : {
"_id": 0,
"Categories": {
"$setDifference": [
{ "$map": {
"input": "$Categories",
"as": "catg",
"in": {
"$cond": [
{ "$ne": [
{ "$ifNull": [ "$$catg.parent", false ] },
false
]},
"$$catg",
false
]}
}
},
[ false ]
]
}
}}
])
db.collection.aggregate(
array(
array("$project" => array(
"_id" => 0,
"Categories" => array(
"$filter" => array(
"input" => "$Categories",
"as" => "catg",
"cond" => array(
"$ne" => array(
array("$ifNull" => array("$$catg.parent", false),
false
)
)
)
)
))
)
)
这是:
db.collection.aggregate(
array(
array("$project" => array(
"_id" => 0,
"Categories" => array(
"$setDifference" => array(
"$map" => array(
"input" => "$Categories",
"as" => "catg",
"in" => array(
"$cond" => array(
"$ne" => array(
array("$ifNull" => array( "$$catg.parent", false ) ),
false
),
"$$catg",
false
)
),
array(false)
)
)
))
)
)