How to filter an array of subdocuments?

I have a document structured as follows:

{ 
"_id" : ObjectId("564d2702d4c68225cb00726f"), 
"list" : [
    {
        "a" : NumberInt(1), 
        "test" : "public"
    }, 
    {
        "a" : NumberInt(2), 
        "test" : "public"
    }, 
    {
        "a" : NumberInt(3), 
        "test" : "public"
    }, 
    {
        "a" : NumberInt(4), 
        "test" : "public"
    }, 
    {
        "a" : NumberInt(5), 
        "test" : "public"
    }
],
"other_fields": ""}

Can I filter the subdocument for a in (1, 5)

My expected result below

{
"_id" : ObjectId("564d2702d4c68225cb00726f"),
"list" : [
    {
        "a" : NumberInt(1),
        "test" : "public"
    },
    {
        "a" : NumberInt(5),
        "test" : "public"
    }
]}

I try to use $elemMatch, but when I use $in, an error has occurred.

+4
source share
2 answers

Starting with MongoDB 3.2, we can use $filterto use this effectively. In the conditional expression, $filterwe need to use the operator $setIsSubsetto check if the given value is in the array. This is mainly due to the fact that we cannot use the query operator $inin $project.

db.collection.aggregate([
    { "$project": { 
        "list": { 
            "$filter": { 
                "input": "$list", 
                "as": "lst", 
                "cond": { "$setIsSubset": [ [ "$$lst.a" ], [ 1, 5 ] ] }
            } 
        } 
    }}
])

MongoDB 3.0.x , , $map $setDifference.

db.collection.aggregate([
    { "$project": { 
        "list": { 
            "$setDifference": [ 
                { "$map": { 
                    "input": "$list", 
                    "as": "lst", 
                    "in": { 
                        "$cond": [
                            { "$setIsSubset": [ [ "$$lst.a" ], [ 1, 5 ] ] },
                            "$$lst",
                            false
                        ] 
                    } 
                }}, 
                [false] 
            ]
        }
    }}
])
+3

: -

db.collection.aggregate([
{ 
    "$match": {
       $or[{ "list.a": NumberInt(1)}, {{ "list.a": NumberInt(5)}}]
    }
},
{
    "$project": {
        "list": {
            "$setDifference": [
                {
                    "$map": {
                        "input": "$list",
                        "as": "o",
                        "in": {
                            "$cond": [
                                {  
                                     $or[{ "list.a": NumberInt(1)}, 
                                         {{ "list.a": NumberInt(5)}}]
                                },
                                "$$o",
                                false
                            ]
                        }
                    }
                },
                [false]
            ]
        }
    }
}
])

: -

{
    "_id" : ObjectId("564d2702d4c68225cb00726f"),
    "list" : [
    {
        "a" : NumberInt(1),
        "test" : "public"
    },
    {
        "a" : NumberInt(5),
        "test" : "public"
    }
]}
0

All Articles