Ahmad Khalil
Ahmad Khalil

Reputation: 45

How to find the best array match

I have quiz1, quiz2 and quiz3, and I want to recommend a quiz to the user , either quiz1 or quiz2 based on the tags from quiz3 without taking every document in the collection and work on them on the application level.

Quiz_1 = {                                                  
    _id:"...",                                                  
    tags:["life-style","personality","sports","soccer"]         
}; 

Quiz_2 = {
    _id:"...",
    tags:["IQ","inteligence","science","maths"]
};

Quiz_3 = {
    _id:"...",                                                  
    tags:["life-style","maths","inteligence","school"]        
};

The best match here is quiz_2, because quiz_3 matches quiz_2 with 2 tags and matches quiz_1 with only 1 tag. (more tag matches equals a better match) How do I do that using mongoose?

Explanation:

I have a collection named "quizzes" and i want mongodb to return the second document when I enter (tags:["life-style","maths","inteligence","school"])

quizzes:
[
  {
    _id:...,
    tags:["life-style","personality","sports","soccer"]]
  },
  {
   _id:"...",
   tags:["IQ","inteligence","science","maths"]
  },
  {
   _id:"...",
   tags:["life-style","maths","inteligence","school"]  
  }
]

Upvotes: 1

Views: 56

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151112

Basically you want to get the $size of the $setIntersection of the comparison array and the "tags" array in the document. Then you $sort to get the largest "size" on top, and finally $limit to one result:

var compare = ["life-style","maths","inteligence","school"];

Quizzes.aggregate([
  { "$match": { "tags": { "$in": compare } } },
  { "$project": {
    "size": {
      "$size": {
        "$setIntersection": [ compare, "$tags" ]
      }
    }
  }},
  { "$sort": { "size": -1 } },
  { "$limit": 1 }
 ])

You speed it up by only examining documents that actually have at least one match by using $in.

Upvotes: 1

Related Questions