猫鼬按填充字段排序 [英] Mongoose sort by populated field

查看:73
本文介绍了猫鼬按填充字段排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我有以下Shemas:

well i have the following shemas:



    var BrandSchema = new Schema({
      name: {
        type: String,
        required: true,
        index: {
          unique: true
        },
        lowercase: true
      },
      logo: {
        type: ObjectId,
        ref: 'Image'
      }
    });

    var FollowActionSchema = new Schema({
      'actionDate': {
        type: Date,
        'default': Date.now
      },
      'brand': {
        type: ObjectId,
        ref: 'Brand'
      },
      'performer': {
        type: ObjectId,
        ref: 'User'
      },
      'type': String // followUser, folloBrand, followMerchant
    });

我想要让用户关注品牌,并按品牌名称排序,为此,我对FollowAction进行了查询,找到了用户执行的所有FollowAction,然后填充了品牌字段.

What i want is getting the user following brands, sorting by brand name, so for do that i did the query to FollowAction and find all the FollowActions that user did and then i populate the brand field.

所以问题是我无法对品牌名称查询进行排序,我唯一知道的方法是返回所有文档并从nodejs应用程序对它们进行排序.有人知道我该怎么做吗?还是我应该更改shema结构?

So the problem is that i can't sort the query for the brand name, the only way i know to do that is by returning all documents and sort them from nodejs app. Anyone knows how can i do that?? or if i should change the shema structure??

我要做的查询是:



       async.waterfall([
        function findActions(next) {
          var options = {
            query: {
              performer: userId,
              $or: [{
                type: 'followBrand'
              }, {
                type: 'followMerchant'
              }]

            },
            projection: {
              actionDate: 1,
              brand: 1,
              merchant: 1,
              type: 1
            },
            sort: '-actionDate',
            pagination: pagination
          };
          utils.limitQuery('FollowAction', options, next);
        },
        function inflate(actions, next) {
          total = actions.count;
          var options = {
            projection: {
              name: 1,
              _id: 1,
              username: 1
            }
          };
          async.eachSeries(actions.result, function(action, done) {
            async.waterfall([
              function inflateAction(done) {
                action.inflate(options, done);
              },
              function addToArray(item, done) {
                trusted.push({
                  _id: item._id,
                  name: utils.capitalize(item.name || item.username),
                  type: item.name ? 'brand' : 'merchant'
                });
                return done(null, item);
              }
            ], done);
          }, next);
        }
      ], function(err) {
        callback(err, trusted, total);
      });

推荐答案

Mongoose API似乎支持对填充字段进行排序,但是有一个错误将其完全破坏:

The Mongoose API does seem to support sorting on populated fields, but there's a bug that breaks it entirely: https://github.com/Automattic/mongoose/issues/2202. You get a result, but it's just plain wrong.

对于少量数据,可以使用Javascript

For small amounts of data, it's fine to sort the result array using Javascript Array.prototype.sort(). Keep in mind that this directly modifies the sorted array though.

在这种情况下,我要做的是将排序键属性添加到要排序的模型的架构中.对于您的示例,您可以执行以下操作:

What I've done in this case is add a sort key property to the schema for the model you want to sort. For your example, you could do:

var FollowActionSchema = new Schema({
  // ...
  'brandSortKey': { type: String },
  'brand': {
    type: ObjectId,
    ref: 'Brand'
  },
  // ...
});

这不是完美的,因为您必须自己使用正确的密钥显式设置此属性:

This isn't perfect, because you'll have to explicitly set this property with the correct key yourself:

var FollowAction = Model('FollowAction', FollowActionSchema);

var aBrand = // some brand object

var f = new FollowAction({
   brand: aBrand._id,
   brandSortKey: aBrand.name
   // other properties
}); 

但是,您可以直接通过Mongoose API(或MongoDB)进行排序:

But, then you can sort directly via the Mongoose API (or MongoDB):

FollowAction.find({})
   .sort({ brandSortKey:1 })
   .exec(function (err, sortedResults) {
       // do something with sorted results.
   });

这篇关于猫鼬按填充字段排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆