考虑以下架构:
{
"_id" : ObjectId("56b9bfb962debd68f8b61340"),
"Name" : "Parent",
"Children" : [
{
"Name" : "A",
"Age" : NumberInt(0)
},
{
"Name" : "B",
"Age" : NumberInt(1)
},
{
"Name" : "C",
"Age" : NumberInt(2)
}
]
}
我正在使用2 $项目阶段。 1过滤"儿童"另一个选择字段除了" Children.Age":
db.collection.aggregate(
[
{
$project: {
Name: 1,
Children: { $filter: {
input: "$Children",
as: "child",
cond: { $gt: ["$$child.Age", 0] }
} }
}
},
{
$project: {
Name: 1,
Children: { Name: 1 }
}
}
]
);
我可以只使用1 $项目阶段吗?
如果可能的话,我想避免使用$ unwind和$ group。
答案 0 :(得分:1)
是的,您可以将管道缩短到一个阶段。为此,您需要使用$map
运算符。
db.collection.aggregate([
{ "$project": {
"Name": 1,
"children": {
"$map": {
"input": {
"$filter": {
"input": "$Children",
"as": "child",
"cond": { "$gt": [ "$$child.Age", 0 ] }
}
},
"as": "ch",
"in":
"$$ch.Name"
}
}
}}
])
另一种方法是使用$setDifference
运算符和$map
运算符运算符。但正如文档中所述:
$setDifference
过滤掉其结果中的重复项,以输出仅包含唯一条目的数组。
db.collection.aggregate([
{ "$project": {
"Name": 1,
"Children": {
"$setDifference": [
{ "$map": {
"input": "$Children",
"as": "child",
"in": {
"$cond": [
{ "$gt": [ "$$child.Age", 0 ] },
"$$child.Name",
false
]
}
}},
[false]
]
}
}}
])
返回:
{
"_id" : ObjectId("56b9bfb962debd68f8b61340"),
"Name" : "Parent",
"Children" : [
"B",
"C"
]
}