0

So, I have the next schema, it's an index of car parts that is used to automatically find the part types according to the keywords.

nameEnglish: {
  type: String
},
keywords: [{
  type: String
}]

I have two documents on the database, one is:

[
  { _id: 1, nameEnglish: 'abcdef', keywords: ['a', 'b', 'c', 'd', 'e', 'f'] },
  { _id: 2, nameEnglish: 'cde', keywords: ['c', 'd', 'e'] }
]

What I am want to do now is query this collection with the MOST number of matched keywords.

myArr = ['b', 'c', 'f'];
db.collection.find({ keywords: { $in: myArr } });

I want this to always return the first document, since it has 3 matched keywords, and the second has only one. How can I achieve this?

2 Answers 2

1

You can try below aggregation using $setIntersection to find the matching elements between keywords array and input array followed by $size to count the matching elements and $sort descending and $limit 1 to output the most matched document.

You can drop the count field using project exclusion {$project:{count:0}} as final stage.

db.col.aggregate(
    [{
        $addFields: {
            "count": {
                $size: {
                    $setIntersection: ["$keywords", myArr]
                }
            }
        }
    }, {
        $sort: {
            "count": -1
        }
    }, {
        $limit: 1
    }]
)
Sign up to request clarification or add additional context in comments.

Comments

1

You need to use aggregation with $setIntersection to get the number of matches, and sort by the no of matches, limit to expected number of results.

db.col.aggregate([
{$addFields : {noOfMatch :{$size :{$setIntersection : ["$keywords", ['b', 'c', 'f']]}}}},
{$sort : {"noOfMatch" : -1}},
{$limit : 1}
])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.