MongoDB - How to find all objects within an array?

2019-01-20 16:28发布

问题:

I'm trying to find all elements within an array called programme. The result of running db.base.find({"programme.title":"News"},{"programme.$.title":"News"}).pretty() is:

{
"_id" : ObjectId("55a48dd3e72db9d63e53478b"),
"programme" : [
    {
        "attributes" : {
            "start" : "20150713010000 -0400",
            "stop" : "20150713013000 -0400",
            "channel" : "I47176.labs.zap2it.com"
        },
        "title" : "News",
        "category" : "News",
        "episode-num" : "SH01831861.0000",
        "new" : true
    }
]
}

But there are many more entries called "News", not just one, as shown above.

I've also tried db.base.find({"programme.title":"News"}).pretty() but that just results in listing a bunch of random entries, whether or not they have the title of "News".

Thanks a lot for the help, and obligatory "apologies for noob question".

回答1:

You can achieve with the help of Aggregation as below :

 db.base.aggregate([
    {$unwind : "$programme"},
    {$match : { "programme.title" : "News" } },
   {$group : { "_id" : "$_id" , "programme" : { $push: "$programme" } } }
]);


回答2:

Projection to a match in MongoDB .find() queries can only return the "first" element matching your conditions.

So to get "multiple" matches your best approach is using .aggregate() and $redact, with first filtering the documents with $match:

db.base.aggregate([
    { "$match": { "programme.title":"News" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [ { "$ifNull": [ "$title", "News" ] }, "News" } ],
            "then": "$$DESCEND",
            "else": "$$PRUNE"
        }}
    }}
])

This "removes" ("redacts") any entries from the array that do not match the "title" you are giving.

This is a good approach since you are not creating more documents in the pipeline using $unwind, which is another way to work with arrays.

The catch is that you cannot have another element in your document with the same property name "title", as the $$DECEND walks into the structure and compares the field names at each level.