You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Mongoose中按指定分类顺序对Product模型数据排序?

Custom Category Sorting for Mongoose Product Model

Got it, so you need to sort your Product documents in that specific custom category order: ['Clothes', 'Accessories', 'Footwears']? Regular Mongoose sort() won't cut it here because it only handles alphabetical or numerical ordering. Instead, we'll use MongoDB's aggregation framework to assign a custom priority value to each category, then sort by that value.

Here's the step-by-step solution:

  • First, define your desired custom order array.
  • Use the $addFields stage to add a temporary sortPriority field, which uses $indexOfArray to get the position of each document's Category in your custom order.
  • Sort the results by this sortPriority field.
  • Optional: Remove the temporary sortPriority field with $project if you don't want it in your final results.

Full Code Example:

const Product = require('./path/to/your/ProductModel');

// Define your desired category order
const customCategoryOrder = ['Clothes', 'Accessories', 'Footwears'];

Product.aggregate([
  // Add a temporary priority field based on custom order
  {
    $addFields: {
      sortPriority: { $indexOfArray: [customCategoryOrder, '$Category'] }
    }
  },
  // Sort by the priority (ascending = your custom order)
  {
    $sort: { sortPriority: 1 }
  },
  // Optional: Remove the temporary sortPriority field from results
  {
    $project: { sortPriority: 0 }
  }
])
.then(sortedProducts => {
  console.log('Products sorted by custom category order:', sortedProducts);
})
.catch(error => {
  console.error('Error sorting products:', error);
});

Handling Categories Outside Your Custom List:

If you have products with categories not in your customCategoryOrder array, $indexOfArray will return -1, which will make them appear first in the results. If you want those to appear last instead, adjust the sortPriority logic with $cond to assign them a priority higher than your last custom category:

sortPriority: {
  $cond: {
    if: { $in: ['$Category', customCategoryOrder] },
    then: { $indexOfArray: [customCategoryOrder, '$Category'] },
    else: customCategoryOrder.length // Assigns a value higher than all custom indices
  }
}

Bonus: Encapsulate as a Model Static Method

To make this reusable, add a static method directly to your Mongoose model so you can call it anywhere easily:

// In your Product model file
const mongoose = require('mongoose')
const { Schema } = mongoose
const schema = new Schema({
  Name: { type: String },
  Category: { type: String },
  Price: { type: Number }
})

// Add custom sorting static method
schema.statics.findSortedByCustomCategory = function() {
  const customOrder = ['Clothes', 'Accessories', 'Footwears'];
  return this.aggregate([
    {
      $addFields: {
        sortPriority: {
          $cond: {
            if: { $in: ['$Category', customOrder] },
            then: { $indexOfArray: [customOrder, '$Category'] },
            else: customOrder.length
          }
        }
      }
    },
    { $sort: { sortPriority: 1 } },
    { $project: { sortPriority: 0 } }
  ]);
};

module.exports = mongoose.model('Product', schema);

Now you can call it with just:

Product.findSortedByCustomCategory().then(sortedProducts => {
  // Use your sorted products
});

内容的提问来源于stack exchange,提问作者Petr Vasilev

火山引擎 最新活动