fgalan
fgalan

Reputation: 12294

Query for at least one key (of a list) in embedded document in MongoDB

I have documents like this in one collection (let's call x) at MongoDB:

{
    "_id" : ...,
    "attrs" : {
        "A2" : {
            "type" : "typeA",
            "value" : "12.2"
        },
        "A3" : {
            "type" : "typeB",
            "value" : "34"
        }
    }
}

In other words, they are documents with an attr field which value is an embedded document which an arbitrary number of keys (in the example A2 and A3 keys are shown).

Given a list of potential keys (e.g. A1, A2, A3) I would like a query to get all document which have at least one of the keys in the given list. My first idea was to use:

db.x.find({"attrs": {$in:[ "A1", "A2", "A3" ]})

but it doesn't work.

I have found a query that solves the problem in the following way:

db.x.find({$or: [ {"attrs.A1": {$exists: true }}, 
                  {"attrs.A2": {$exists: true }}, 
                  {"attrs.A3": {$exists: true }} ] })

However, I wonder if there is a better and more "compact" solution, like the first find() example that didn't work.

Upvotes: 1

Views: 1238

Answers (2)

Sede
Sede

Reputation: 61225

You can use the $where operator and the Array.prototype.some() method.

db.collection.find({ $where: function(){ 
        return Object.keys(this.attrs).some(function(elt){ 
            return ( ["A1", "A2", "A3"].indexOf(elt) != -1 ); }) 
        }
    }
)

Upvotes: 1

Vishwas
Vishwas

Reputation: 7067

You can do something inverse about what you want. If you want to get attrs which have at least one key in it, you can use $ne of mongo like-

db.collection.find({"attrs":{$ne:{}}})

By checking if attrs is empty or not you can get desired result. Hope this will useful to you.

Upvotes: 1

Related Questions