0

I'm using mongodb in a nodejs project, in which I have a collection of users :

{ "_id" : ObjectId("1"), "firstName": "John", "lastName" : "Doe", "age":20 }
{ "_id" : ObjectId("2"), "firstName": "Jane", "lastName" : "Doe", "age":22 }
{ "_id" : ObjectId("3"), "firstName": "Bob", "lastName" : "Smith","age": 32 }
{ "_id" : ObjectId("4"), "firstName": "John", "lastName" : "Smith","age":40}
{ "_id" : ObjectId("5"), "firstName": "John", "lastName" : "Deer","age":66}

I'd like a query to return an array of document ids matching the array of users by their first and last name ordered by the array I've given here

This is what I'm trying to fiddle with:

var usersToFind = [
  { firstName: "John", lastName: "Smith"},
  { firstName: "John", lastName:"Doe"}
];

db.collection('users').then(users => users.aggregate([
   { $match : { /* what to put here? */ } },
   { $addFields : { '__order' : { $indexOfArray : [usersToFind, /* Missing here something */} } },
   { $sort : { '__order' : 1 } }
]).toArray(results => {
  console.log(results);
  // Should print ["ObjectId(4)", "ObjectId(1)"];
});

I'm probably missing something fundamental about how to work with mongodb due to my limited knowledge of it.

I'd be grateful if you could help me solve the query or show me a better way to achieve it.

I could always iterate my usersToFind array and find documents one by one, but I'd like to use a single query here. Another approach is to use $or and $and

Thank you

mati.o
  • 1,398
  • 1
  • 13
  • 23
  • Have you tried find() https://docs.mongodb.com/manual/reference/method/db.collection.find/ – frozen Jul 09 '17 at 14:16
  • Surely I've tried. I made a slight breakthrough using db.collection('users').find( { $or : usersToFind }), now i'd like to sort them by the order they appear in the array - to this I guess aggregate should come to help – mati.o Jul 09 '17 at 14:34

2 Answers2

2

Using an $or query with a projection will get you most of the way there:

db.collection('users').find({$or: usersToFind}).project({_id: 1}).toArray((err, docs) => {
  console.log(docs);
});

But the sorting is another matter, as MongoDB doesn't have any built-in support for custom sorting. See this post for some ways of handling that.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Thanks! Since mongo 3.4 we can use `aggregate` to `$sort` results, I'll edit your answer later to provide a working example for my case once it works – mati.o Jul 09 '17 at 18:09
0

You can use find(). Here is an example:

db.collection('users').find(
   {
     "firstName": "John",
     "lastName": "Doe"
   }
)

Here is the documentation.

zoecarver
  • 5,523
  • 2
  • 26
  • 56
  • This is how you fetch a single document, which is plain in simple but quite not my case, I needed to get multiple documents described by some of their fields. This can be achieved using `$or`. In my particular example I needed to get the ids of both John Doe and John Smith but not John Deer, Jane or Bob. – mati.o Jul 09 '17 at 18:12