如何用MongoDB过滤子文档中的数组

如何用MongoDB过滤子文档中的数组

我在子文档中有这样的数组

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 1
        },
        {
            "a" : 2
        },
        {
            "a" : 3
        },
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]}

我能过滤一个>3的子文档吗?

我的预期结果如下

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]}

我试着用$elemMatch但是返回数组中的第一个匹配元素。

我的问题是:

db.test.find( { _id" : ObjectId("512e28984815cbfcb21646a7") }, { 
    list: { 
        $elemMatch: 
            { a: { $gt:3 } 
            } 
    } } )

结果返回数组中的一个元素。

{ "_id" : ObjectId("512e28984815cbfcb21646a7"), "list" : [ { "a" : 4 } ] }

我试着用聚合$match但不工作

db.test.aggregate({$match:{_id:ObjectId("512e28984815cbfcb21646a7"), 'list.a':{$gte:5}  }})

它返回数组中的所有元素

{
    "_id" : ObjectId("512e28984815cbfcb21646a7"),
    "list" : [
        {
            "a" : 1
        },
        {
            "a" : 2
        },
        {
            "a" : 3
        },
        {
            "a" : 4
        },
        {
            "a" : 5
        }
    ]}

我能过滤数组中的元素以得到预期的结果吗?


慕勒3428872
浏览 1928回答 3
3回答

哆啦的时光机

使用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'}}})产出:{   "result": [     {       "_id": ObjectId("512e28984815cbfcb21646a7"),       "list": [         4,         5       ]     }   ],   "ok": 1}MongoDB 3.2更新从3.2版开始,您可以使用新的$filter聚合运算符以更有效地完成此操作,只需包括list控件期间所需的元素。$project:db.test.aggregate([     { $match: {_id: ObjectId("512e28984815cbfcb21646a7")}},     { $project: {         list: {$filter: {             input: '$list',             as: 'item',             cond: {$gt: ['$$item.a', 3]}         }}     }}])

拉丁的传说

如果需要多个匹配的子文档,上述解决方案最好。$elemMatch如果需要单个匹配的子文档作为输出,也非常有用。db.test.find({list: {$elemMatch: {a: 1}}}, {'list.$': 1})结果:{   "_id": ObjectId("..."),   "list": [{a: 1}]}

守候你守候我

使用$Filter聚合根据指定的条件选择要返回的数组的子集。返回只包含与条件匹配的元素的数组。返回的元素按原来的顺序排列。db.test.aggregate([ &nbsp;&nbsp;&nbsp;&nbsp;{$match:&nbsp;{"list.a":&nbsp;{$gt:3}}},&nbsp;//&nbsp;<--&nbsp;match&nbsp;only&nbsp;the&nbsp;document&nbsp;which&nbsp;have&nbsp;a&nbsp;matching&nbsp;element &nbsp;&nbsp;&nbsp;&nbsp;{$project:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list:&nbsp;{$filter:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input:&nbsp;"$list", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as:&nbsp;"list", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cond:&nbsp;{$gt:&nbsp;["$$list.a",&nbsp;3]}&nbsp;//<--&nbsp;filter&nbsp;sub-array&nbsp;based&nbsp;on&nbsp;condition &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}} &nbsp;&nbsp;&nbsp;&nbsp;}}]);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

MongoDB