【问题标题】:Mongoose sorting subdocument populated猫鼬排序子文档填充
【发布时间】:2016-08-17 22:02:27
【问题描述】:

我有一个 Mongoose 模型,其中包含需要填充的路径:

var adsSchema = new Schema({                                                                   
    price:      { type: Number, min: 0, required: true }, 
    author:     { type: ObjectId, ref: 'Users', required: true }, 
    title:      { type: String, required: true }, 
    date:       { type: Date, default: Date.now }, 
    offers:     [{                                
        price:      { type: Number, required: true },                                          
        date:       { type: Date, default: Date.now },                                         
        offerBy:    { type: ObjectId, ref: 'Users', required: true }                           
    }],                                                                                        
    category:   { type: ObjectId },                                                            
    images:     [{                                                                             
        type: ObjectId,                                                                        
        ref: 'Images'                                                                          
    }],                                                                                        
    videos:     [String]                                                                       
});

在某些 GET 请求中,我需要填充许多字段,特别是按“价格”升序排序的报价。

由于那里显示了 Mongoose 的文档 (http://mongoosejs.com/docs/api.html#query_Query-populate),您可以按子路径排序。

我的问题是事实并非如此。

有我的代码正在这样做:

Ads.findOne({ _id: adId })
  .populate({ path: 'author', select: 'firstName lastName' })
  .populate('images')
  .populate({ path: 'offers', options: { sort: { 'price': -1 } })
  .populate({ path: 'category', select: 'name' })
  .exec(function (err, ad) {
     if (err)
       deferred.reject({ status: 500, message: 'Database error.' });
     else if (!ad)
       deferred.reject({ status: 500, message: 'The ad doesn\'t exist!.' });
     else {
                deferred.resolve(ad.toJSON());
     }
})

我已尽可能多地阅读此处或 Mongoose 邮件列表中给出的问题/答案:

我知道不可能从子文档结果中对文档结果进行排序,好的。但我只想对那个子文档进行排序,而且只有这个。这里的一些回复似乎说这是可能的:

我有两个问题:

  • 是否有可能(如 Mongoose 文档所写)在填充期间对子文档进行排序?
  • 这是否与我不只是将 ObjectId 链接到其他 Schema 的事实有关?

感谢您的回答;)

【问题讨论】:

    标签: node.js mongodb sorting mongoose-populate


    【解决方案1】:

    就我个人而言,我不会尽可能使用“填充”。过去我经历过很多麻烦。所以,我不知道如何在填充时进行排序。

    您可以在聚合上使用 $lookup 方法,而不是使用填充,您可以轻松地对任何字段进行排序。它与“人口”几乎相同。

    Ads.aggregate([
            {
              $lookup: {
                from: 'Users',
                localField: 'author',
                foreignField: '_id',
                as: 'authorName'
              }
            },
            {
              $lookup: {
                from: 'Images',
                localField: 'images',
                foreignField: '_id',
                as: 'image'
              }
            },
            {
              $lookup: {
                from: 'categories',
                localField: 'category',
                foreignField: '_id',
                as: 'category'
              }
            },
            {
              $project: {
                'authorName.firstName': 1,
                'image.imagePath': 1,
                'category.categoryName': 1,
                '_id': 0
              }
            },
            {
              $sort : { 'authorName.firstName' : -1} 
            }
    
          ]).exec(function(err, adss) {
    
          });
    

    我没有正确检查所有字段。请以这种方式实现您的模型,希望这能给您一些想法。祝你好运

    【讨论】:

    • 如何对带有子文档的主文档应用 SORT?
    【解决方案2】:

    我找到了解决方案,这是我第二个问题的回答。

    当您像我的问题一样在架构中编写子文档时,您并没有在一个模型和另一个模型之间创建“关系”。这意味着填充方法根本不起作用。

    您必须引用 ObjectId 和关联的模型才能使用填充,以及为您提供 Mongoose 的选项。这是一个例子:

    var adsSchema = new Schema({
        price:      { type: Number, min: 0, required: true },
        author:     { type: ObjectId, ref: 'Users', required: true },
        offers:     [{ 
            type: ObjectId,
            ref: 'Offers'
        }],
        videos:     [String]
    });
    

    现在,.populate 方法正在工作,因为 Mongoose(以及 MongoDB)可以在另一个 Collection 上执行子查询并对其进行排序。以前不是这样,因为它在同一个 Model 中,所以 Mongoose 不会对同一个 Collection 执行子查询(我似乎理解它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-16
      • 2017-05-07
      • 2021-02-11
      • 2021-10-07
      • 2015-10-01
      • 2015-11-27
      • 2015-07-28
      • 2021-08-29
      相关资源
      最近更新 更多