mongodb 如何使用MongoDB过滤子文档中的数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15117030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to filter array in subdocument with MongoDB
提问by chenka
I have array in subdocument like this
我在子文档中有这样的数组
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"list" : [
{
"a" : 1
},
{
"a" : 2
},
{
"a" : 3
},
{
"a" : 4
},
{
"a" : 5
}
]
}
Can I filter subdocument for a > 3
我可以过滤子文档> 3
My expect result below
我的预期结果如下
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"list" : [
{
"a" : 4
},
{
"a" : 5
}
]
}
I try to use $elemMatch
but returns the first matching element in the array
我尝试使用$elemMatch
但返回数组中的第一个匹配元素
My query:
我的查询:
db.test.find( { _id" : ObjectId("512e28984815cbfcb21646a7") }, {
list: {
$elemMatch:
{ a: { $gt:3 }
}
}
} )
The result return one element in array
结果返回数组中的一个元素
{ "_id" : ObjectId("512e28984815cbfcb21646a7"), "list" : [ { "a" : 4 } ] }
and I try to use aggregate with $match
but not work
我尝试使用聚合$match
但不起作用
db.test.aggregate({$match:{_id:ObjectId("512e28984815cbfcb21646a7"), 'list.a':{$gte:5} }})
It's return all element in array
它返回数组中的所有元素
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"list" : [
{
"a" : 1
},
{
"a" : 2
},
{
"a" : 3
},
{
"a" : 4
},
{
"a" : 5
}
]
}
Can I filter element in array to get result as expect result?
我可以过滤数组中的元素以获得预期结果吗?
回答by JohnnyHK
Using aggregate
is the right approach, but you need to $unwind
the list
array before applying the $match
so that you can filter individual elements and then use $group
to put it back together:
使用aggregate
是正确的做法,但你需要$unwind
在list
应用前阵列$match
,这样就可以过滤单个元素,然后用$group
把它重新走到一起:
db.test.aggregate([
{ $match: {_id: ObjectId("512e28984815cbfcb21646a7")}},
{ $unwind: '$list'},
{ $match: {'list.a': {$gt: 3}}},
{ $group: {_id: '$_id', list: {$push: '$list.a'}}}
])
outputs:
输出:
{
"result": [
{
"_id": ObjectId("512e28984815cbfcb21646a7"),
"list": [
4,
5
]
}
],
"ok": 1
}
MongoDB 3.2 Update
MongoDB 3.2 更新
Starting with the 3.2 release, you can use the new $filter
aggregation operator to do this more efficiently by only including the list
elements you want during a $project
:
从 3.2 版本开始,您可以使用新的$filter
聚合运算符来更有效地执行此操作,方法是list
在 a 期间仅包含您想要的元素$project
:
db.test.aggregate([
{ $match: {_id: ObjectId("512e28984815cbfcb21646a7")}},
{ $project: {
list: {$filter: {
input: '$list',
as: 'item',
cond: {$gt: ['$$item.a', 3]}
}}
}}
])
回答by keshav
Above solution works best if multiple matching sub documents are required. $elemMatchalso comes in very use if single matching sub document is required as output
如果需要多个匹配的子文档,上述解决方案效果最佳。 如果需要单个匹配的子文档作为输出,$elemMatch也非常有用
db.test.find({list: {$elemMatch: {a: 1}}}, {'list.$': 1})
Result:
结果:
{
"_id": ObjectId("..."),
"list": [{a: 1}]
}
回答by Rahul
Selects a subset of the array to return based on the specified condition. Returns an array with only those elements that match the condition. The returned elements are in the original order.
根据指定条件选择要返回的数组子集。返回一个仅包含与条件匹配的元素的数组。返回的元素按原始顺序排列。
db.test.aggregate([
{$match: {"list.a": {$gt:3}}}, // <-- match only the document which have a matching element
{$project: {
list: {$filter: {
input: "$list",
as: "list",
cond: {$gt: ["$$list.a", 3]} //<-- filter sub-array based on condition
}}
}}
]);