Home > Mobile >  Sort with Mongoose by the number of respected conditions
Sort with Mongoose by the number of respected conditions

Time:11-03

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
    }
  }
])

Playground demonstration here

  • Related