Search code examples
mongodbmongoosemongodb-querymongoose-schema

Sorting by the contents of an array


I want to receive all items first where the sort designation matches. An article is assigned to a category. However, a user can specify several categories (array). So I want to see if an item matches a category from the array and if so, it will be returned with a higher rating.

 const artikel = await Artikel.find({
  art: req.params.filter,
  userId: { $ne: req.body.userId },
})
 .sort([req.body.kategorie, 1]) //USER = req.body.kategorie is an Array ['KFZ','Garden'] 
 .limit(10)
 .skip(req.body.page * 10);

Articel Schema:

 const ArtikelSchema = mongoose.Schema(

 ....

   kategorie: {
    type: String,
    required: true,
   },

 )

User Schema:

 const UserSchema = mongoose.Schema(

 ...

 kategorie: {
  type: [String],
  default: [],
 },

 )

Solution

  • You can use aggregate instead of find and add a temporary helper field to sort the result

      const artikel = await Artikel.aggregate([
        {
          $match: {
            art: req.params.filter,
            userId: { $ne: req.body.userId },
          } // your FilterQuery
        },
        {$addFields: {_prior: {$in: ["$kategorie", req.body.kategorie]}}}, // add a tmp field "_prior", which is true if the array `req.body.kategorie` contains the value of `kategorie` field
        {$sort: {_prior: -1}}, // sort by the tmp field added, descending because true > false
        {$skip: req.body.page * 10},
        {$limit: 10},
        {$unset: "_prior"}, // remove the tmp field from output
      ])
    

    See more on Mongo's doc