Reputation: 702
An item in collection contains an array of strings. I would like to find and sort items with most matching elements in array.
Consider a collection:
[
{
"item_name":"Item_1",
"tags":["A","B","C","D","E"]
},
{
"item_name":"Item_2",
"tags":["A","B","D","E","G"]
},
{
"item_name":"Item_3",
"tags":["B","C","E","H"]
}
]
I want to sort the collection based on an array like ["B","D","G","F"] which will return
[
{
"item_name":"Item_2",
"tags":["A","B","D","E","G"]
},
{
"item_name":"Item_1",
"tags":["A","B","C","D","E"]
},
{
"item_name":"Item_3",
"tags":["B","C","E","H"]
}
]
The expected order will be Item_2,Item_1 and then Item_3 since,
If not in mongodb, JavaScript methods will also be appreciated
Upvotes: 2
Views: 566
Reputation: 5245
If the values in tags
are unique, you can use the size of the intersections of tags
and the query array using $size
and $setIntersection
db.collection.aggregate([
{
$set: {
matchedCount: {
$size: {
$setIntersection: ["$tags", ["B","D","G","F"]]
}
}
}
},
{
$sort: {
matchedCount: -1
}
}
])
Upvotes: 5
Reputation: 14402
You can use $setIntersection
to get the number of intersecting items and then $sort
based on the computed score.
db.collection.aggregate([
{
$project: {
_id: 0,
item_name: "$item_name",
tags: "$tags",
score: {
$let: {
vars: {
intersection: {
$setIntersection: [
"$tags",
[
"B",
"D",
"G",
"F"
]
]
}
},
in: {
$size: "$$intersection"
}
}
}
}
},
{
$sort: {
score: -1
}
}
])
https://mongoplayground.net/p/tpDTtVKetFT
Upvotes: 2