0

I have documents like this:

db.planet.insert({ 
    name: 'Earth',
    stuff: {
        'grass': 'green',
        'sky': 'blue',
        'sea': 'blue'
    }
})
db.planet.insert({ 
    name: 'Mars',
    stuff: {
        'dust': 'red',
        'sky': 'yellow'
    }
})

I want to find all planets that have at least some blue stuff (only earth in this case). How can I do that?

Catch: I tried solving this by using an array (instead of object) for stuff (stuff: [ { k: 'grass', v: 'green'},... ]) but I also need to be able to update (upsert to be exact) value of some stuff. For instance I must be able to do this:

db.planet.update({ name: 'Mars' }, {
    '$set': { 
        'stuff.canals': 'brown', 
        'stuff.dust': 'reddish' 
    } 
})

So, how can I find the planets with something blue on them? :)

johndodo
  • 17,247
  • 15
  • 96
  • 113

1 Answers1

2

Use the $or operator. The $or operator value should be an array, with the array containing conditions of which at least one must be true.

In your case, given the field names you have mentioned:

 db.planet.find($or:[
   {"stuff.sky":"blue"},
   {"stuff.grass":"blue"},
   {"stuff.sea":"blue"},
   {"stuff.dust":"blue"},
   {"stuff.canals":"blue")
 ])

See http://docs.mongodb.org/manual/reference/operator/or/
As there are a quite a number of different fields you want to query, you may want to keep an array of all these field names somewhere so you can generate the $or array programmatically.

I don't think there's a way to make the query without knowing the field names in advance. See mongodb query without field name .

Community
  • 1
  • 1
Myrne Stol
  • 11,222
  • 4
  • 40
  • 48
  • Meryn, thanks! Since I don't know the field names your solution is not suitable for my case, but there is an acceptable solution at the [linked question](http://stackoverflow.com/questions/10901151/mongodb-query-without-field-name). Not sure how I missed that question. :) – johndodo Mar 26 '13 at 10:57