7

I have a Person object in mongoose, and that person object has multiple things (each thing has a unique ID).

person1 = {
  things[{id: 1, name: 'one'},{id:2, name: 'two'}]
}
person2 = {
  things[{id: 3, name: 'three'},{id:4, name: 'four'}]
}

then query:

Person.findOne({'things.id': 2},{'things.$': 1}, function(err, person) { ...

This works great but I am searching through all Person objects (which there could be a lot of). In this case I know the id of the Person I need and some unique id of a 'thing'. Its probably a lot faster to get the Person by id:

Person.findById(personId, function(err, person) { ...

Then loop over all the things to find the right one:

var thing
person.things.forEach(function(t) {
  if (t.id == thingId) {
    thing = t;
  }
});

What I am wondering is if there is a better way. I.E. can I query the Person collection by id to get just one Person then filter out just the thing I am looking for (without the ugly loop)?

Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
lostintranslation
  • 23,756
  • 50
  • 159
  • 262
  • 9
    What does `things.$` mean? What does the `$` refer to/do? – sinθ Dec 31 '13 at 15:14
  • 3
    The `$` is a positional operator. You can find more details about it in the [Mongo docs](http://docs.mongodb.org/manual/reference/operator/projection/positional/) ;) – Preview Oct 23 '14 at 13:38

1 Answers1

19

You can include both id terms in a single query and the single element projection will still work:

Person.findOne({_id: personId, 'things.id': 2}, {'things.$': 1}, 
    function(err, person) { ...
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • So that will query on Person first (which should be fast), then on a specific thing for that person? That is awesome, thanks! – lostintranslation Mar 05 '13 at 13:58
  • So does this mean that the person object will be returned with only one element in the things array, that being the thing we are looking for in the query? – Ulysses Alves Dec 08 '15 at 15:41
  • Nice. I am looking now for a way to do this but with findOneAndUpdate, because I need to update only a specific element of a document array. Do you have any ideas on how to accomplish this? – Ulysses Alves Dec 08 '15 at 16:30
  • 1
    @UlyssesAlves See http://stackoverflow.com/questions/17678327/how-to-update-particular-array-element-in-mongodb – JohnnyHK Dec 08 '15 at 16:45