I want to make a search function with mongoose, and I have to be able to make a research with multiple fields (with Mongoose, in NodeJS).
So, I do something like this :
const result = await myModel.find({
$or [{condition1: "value1"}, {condition2: "value2"}, etc...]
});
But, I want to sort the result by the number of condition the object returned have. Like :
If I have 2 conditions, I want to display first the objects respecting the 2 conditions, then the objects respecting the 1st condition, and finally the objects respecting the 2nd condition.
Do you guys know how I can do this? :)
Thanks in advance !
CodePudding user response:
In general, a document either matches a query predicate or it doesn't. There isn't really a concept of one document matching "better" than another. So it looks like you'll want to generate a custom value in a new field and sort on that. This will need to be done via an aggregation.
So after the $match
, we'll want an $addFields
stage that effectively duplicates the query predicates. For each one it will be wrapped in a conditional statement ($cond
) where we add 1
for a match or 0
otherwise, e.g.:
{
$cond: [
{
$eq: [
"$condition1",
"value1"
]
},
1,
0
]
}
Then there will be a $sum
pulling them together to generate the final score to sort on.
Taken together, the aggregation will look something like this:
db.collection.aggregate([
{
$match: {
$or: [
{
condition1: "value1"
},
{
condition2: "value2"
}
]
}
},
{
$addFields: {
sortField: {
"$sum": [
{
$cond: [
{
$eq: [
"$condition1",
"value1"
]
},
1,
0
]
},
{
$cond: [
{
$eq: [
"$condition2",
"value2"
]
},
1,
0
]
}
]
}
}
},
{
$sort: {
"sortField": -1
}
}
])