How do I use $ elemMatch for cumulative projection?

This is my object:

{ "_id" : ObjectId("53fdcb6796cb9b9aa86f05b9"), "list" : [ "a", "b" ], "complist" : [ { "a" : "a", "b" : "b" }, { "a" : "c", "b" : "d" } ] }

      

And this is what I want to accomplish: check if the "list" contains a specific item and only gets the "a" field from the complist objects when reading the document regardless of any of those values. I am creating a forum system, this is a request that will return the forum details. I need to read the forum information knowing if the user is on the forum whitelist.

With find I can use query

db.itens.find({},{list:{$elemMatch:{$in:["a"]}}})

      

to get only the first element that matches a specific value. That way, I can just check if the returned array hasn't returned and I know if the "list" contains the value I'm looking for. I cannot do this on demand because I need a document independently of it containing the value I am looking for in the value "list". I need a document And I know if the "list" has a specific meaning.

With an aggregate, I can use the query

db.itens.aggregate({$project:{"complist.a":1}})

      

to read only the "a" field of the objects contained in the complist. This will get basic information about the forums, I don't want all the information about threads, just a couple of things.

But when I try to use the query

db.itens.aggregate({$project:{"complist.b":1,list:{$elemMatch:{$in:["a"]}}}})

      

to try to do both, it throws an error saying the $ elemMatch statement is not valid.

Am I doing something wrong with $ elemMatch in aggregate? Is there a better way to do this?

+3


source to share


4 answers


Ok, you can use "array.field" in the search projection block.

 db.itens.find({},{"complist.b":1,list:{$elemMatch:{$in:["a"]}}})

      



did what i needed.

-five


source


For some reason, $ elemMatch doesn't work in aggregation. You need to use the new $ filter statement in Mongo 3.2. See https://docs.mongodb.org/manual/reference/operator/aggregation/filter/



+5


source


In fact, the simplest solution is to just expand your array and then match the relevant documents. You can complete the relevant documents again using $ group and $ push.

+3


source


Although the question is old, here is my contribution in November 2017.

I had a similar problem and two successive match operations worked for me. The code below is a subset of all my code and I changed the element names so it is not tested. Either way, it should point you in the right direction.

db.collection.aggregate([
    {
        "$match": {
            "_id": "ID1"
        }
    },
    {
        "$unwind": "$sub_collection"
    },
    {
        "$match": {
            "sub_collection.field_I_want_to_match": "value"
        }
    }
])

      

+1


source







All Articles