Trevor
Trevor

Reputation: 1414

MongoDB: Lookup Best Possible Match within Array [Mongoose]

Here's the People database:

[
  #1 {qualities: ['brown', 'nice', 'happy' 'cool' 'cheery']}
  #2 {qualities: ['blue', 'okay', 'happy' 'decent' 'cheery']}
  #3 {qualities: ['green', 'alright', 'happy' 'cool' 'cheery']}
]

Here's the People schema and model:

var peopleSchema = mongoose.Schema({
  qualities: [],
});

var People = mongoose.model('People', peopleSchema);

Here's the query that actually works:

People.find({'qualities': "cheery"}, function(err, people) {
   console.log(people)
});

^^ Problem: Can't use more than one word. ^^

Here's the type of query that I'd like:

People.find({'qualities': ["brown", "happy", "cool"]}, function(err, persons) {
  console.log(persons)
});

Hopeful result would be person #1 followed by person #3 followed by person #2.

Upvotes: 0

Views: 118

Answers (1)

Shaishab Roy
Shaishab Roy

Reputation: 16805

You can use $in operator

{ field: { $in: [<value1>, <value2>, ... <valueN> ] } } 

so query can be like

People.find({'qualities': {$in: ["brown", "happy", "cool"]}}, function(err, persons) {
  console.log(persons)
});

If you want to get data according to maximum match document first then you need to use aggregate query

say your data like:

{_id:1, qualities: ['brown', 'nice', 'happy' 'cool' 'cheery']}
{_id:2, qualities: ['blue', 'okay', 'happy' 'decent' 'cheery']}
{_id:3, qualities: ['green', 'alright', 'happy' 'cool' 'cheery']}

then your query will be like

People.aggregate([
  {$unwind:"$qualities"},
  {$match:{'qualities': {$in: ["brown", "happy", "cool"]}}},
  {$group:{_id:"$_id",count:{$sum:1}}},
  {$sort:{count:-1}}
]).exec(function(err, persons) {
      console.log(persons)
});

it will return 1, 3,2 because for first one matched with 3 items, third one matched with 2 items and second one matched with 1 item

Upvotes: 4

Related Questions