3

I have a document with the following structure: {_id: 'fkwjefioew', genres: [{_id: 'fewkjfewf', 'name': "Shooter"}, {...}, ...]} I need to be able to query using mongo's $in to see if the doc has the genre name of the passed parameter. For example, if I passed the parameter of "Shooter" to the query, I would want all the documents where one of the objects within that documents generes array holds the name "Shooter". What would be the easiest way to achieve this? Thanks!

TDmoneybanks
  • 478
  • 1
  • 7
  • 20

1 Answers1

3

You would want to use $elemMatch for this.

{"genres": { "$elemMatch" :  {"name": "Shooter"} } }
// or
{"genres": { "$elemMatch" :  {"name": { "$in": ["Shooter"] } } } }

https://docs.mongodb.com/manual/reference/operator/query/elemMatch/

You could also use the mongodb dot notation and it will pretty much work like you would except:

{"genres.name": "Shooter"}
// or
{"genres.name": { "$in": ["Shooter"]}}

Mongodb knows how to interpret this in case genres is an array. Just keep in mind that the dot notation query is slightly ambiguous, since it will will also match to the name property in case the genres property is not an array. For example, this doc would match:

{"genres": { "name": "Shooter" } }

In all cases you can index the name property in the genres array and the index would be used for the lookups.

db.collection.createIndex({'genres.name': 1})

https://docs.mongodb.com/manual/reference/glossary/#term-dot-notation

https://docs.mongodb.com/manual/reference/operator/query/in/

Willem D'Haeseleer
  • 19,661
  • 9
  • 66
  • 99
  • 2
    This answer is right for this specific case, but note that you might get unexpected behaviour if you try to query multiple fields at the same time. If you are doing that, $elemMatch is preferred for reasons stated in this answer: https://stackoverflow.com/questions/18335248/dot-notation-vs-elemmatch – Alexander Kuzmin May 09 '16 at 01:15
  • 1
    @AlexanderKuzmin Thx for pointing that out Alexander, I augmented the answer to reflect your feedback. – Willem D'Haeseleer May 09 '16 at 02:52