Javascript Mongoose,按填充字段对查询进行排序

Javascript Mongoose,按填充字段对查询进行排序,javascript,node.js,mongodb,sorting,mongoose,Javascript,Node.js,Mongodb,Sorting,Mongoose,据我所知,可以使用Mongoose()对填充的文档进行排序 我正在寻找一种按一个或多个填充字段对查询进行排序的方法 考虑这两种猫鼬模式: var Wizard = new Schema({ name : { type: String } , spells : { [{ type: Schema.ObjectId, ref: 'Spell' }] } }); var Spell = new Schema({ name : { type: String } , dam

据我所知,可以使用Mongoose()对填充的文档进行排序

我正在寻找一种按一个或多个填充字段对查询进行排序的方法

考虑这两种猫鼬模式:

var Wizard = new Schema({
    name  : { type: String }
, spells  : { [{ type: Schema.ObjectId, ref: 'Spell' }] }
});

var Spell = new Schema({
    name    : { type: String }
,   damages : { type: Number }
});
示例JSON:

[{
    name: 'Gandalf',
    spells: [{
            name: 'Fireball',
            damages: 20
        }]
}, {
    name: 'Saruman',
    spells: [{
            name: 'Frozenball',
            damages: 10
        }]
}, {
    name: 'Radagast',
    spells: [{
            name: 'Lightball',
            damages: 15
        }]
}]
我想根据这些巫师的法术伤害对他们进行分类,比如:

WizardModel
  .find({})
  .populate('spells', myfields, myconditions, { sort: [['damages', 'asc']] })
// Should return in the right order: Saruman, Radagast, Gandalf
事实上,在查询之后,我正在手动进行这些排序,并希望对其进行优化。

问问自己(以下是答案):

我想要什么? 按法师的法术伤害排序(这应该是一个传统的字段,可能是法术伤害的总和)

我所做的: 我已经把巫师的法术分类了

你应该做什么:
Wizard.find({}).sort({power:'asc'})
然后填充咒语,做任何你喜欢的事情。 力量是向导中的另一个领域。你需要它,因为即使你填充了你的法术,你也会有一系列的法术,这对你没有帮助


希望这有帮助。

您可以隐式地只指定填充方法所需的参数:

WizardModel
  .find({})
  .populate({path: 'spells', options: { sort: [['damages', 'asc']] }})
看看 下面是上面链接中的一个示例

doc
.populate('company')
.populate({
  path: 'notes',
  match: /airline/,
  select: 'text',
  model: 'modelName'
  options: opts
}, function (err, user) {
  assert(doc._id == user._id) // the document itself is passed
})

尽管这是一篇很老的文章,我还是想通过MongoDB聚合查找管道分享一个解决方案

重要的是:

 {
      $lookup: {
        from: 'spells',
        localField: 'spells',
        foreignField:'_id',
        as: 'spells'
      }
    },
    {
      $project: {
        _id: 1,
        name: 1,
        // project the values from damages in the spells array in a new array called damages
        damages: '$spells.damages',
        spells: {
          name: 1,
          damages: 1
        }
      }
    },
    // take the maximum damage from the damages array
    {
      $project: {
        _id: 1,
        spells: 1,
        name: 1,
        maxDamage: {$max: '$damages'}
      }
    },
    // do the sorting
    {
      $sort: {'maxDamage' : -1}
    }
下面是一个完整的例子

'use strict';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/lotr');

const db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {



  let SpellSchema = new Schema({
    name    : { type: String },
    damages : { type: Number }
  });

  let Spell = mongoose.model('Spell', SpellSchema);

  let WizardSchema = new Schema({
    name: { type: String },
    spells: [{ type: Schema.Types.ObjectId, ref: 'Spell' }]
  });

  let Wizard = mongoose.model('Wizard', WizardSchema);

  let fireball = new Spell({
    name: 'Fireball',
    damages: 20
  });

  let frozenball = new Spell({
    name: 'Frozenball',
    damages: 10
  });

  let lightball = new Spell({
    name: 'Lightball',
    damages: 15
  });

  let spells = [fireball, frozenball, lightball];

  let wizards = [{
    name: 'Gandalf',
    spells:[fireball]
  }, {

    name: 'Saruman',
    spells:[frozenball]
  }, {
    name: 'Radagast',
    spells:[lightball]
  }];

  let aggregation = [
    {
      $match: {}
    },
    // find all spells in the spells collection related to wizards and fill populate into wizards.spells
    {
      $lookup: {
        from: 'spells',
        localField: 'spells',
        foreignField:'_id',
        as: 'spells'
      }
    },
    {
      $project: {
        _id: 1,
        name: 1,
        // project the values from damages in the spells array in a new array called damages
        damages: '$spells.damages',
        spells: {
          name: 1,
          damages: 1
        }
      }
    },
    // take the maximum damage from the damages array
    {
      $project: {
        _id: 1,
        spells: 1,
        name: 1,
        maxDamage: {$max: '$damages'}
      }
    },
    // do the sorting
    {
      $sort: {'maxDamage' : -1}
    }
  ];
  Spell.create(spells, (err, spells) => {
    if (err) throw(err);
    else {
      Wizard.create(wizards, (err, wizards) =>{
        if (err) throw(err);
        else {
          Wizard.aggregate(aggregation)
          .exec((err, models) => {
            if (err) throw(err);
            else {
              console.log(models[0]); // eslint-disable-line
              console.log(models[1]); // eslint-disable-line
              console.log(models[2]); // eslint-disable-line
              Wizard.remove().exec(() => {
                Spell.remove().exec(() => {
                  process.exit(0);
                });
              });
            }
          });
        }
      });
    }
  });
});

这是猫鼬文件的样本

var PersonSchema = new Schema({
    name: String,
    band: String
});

var BandSchema = new Schema({
    name: String
});
BandSchema.virtual('members', {
    ref: 'Person', // The model to use
    localField: 'name', // Find people where `localField`
    foreignField: 'band', // is equal to `foreignField`
    // If `justOne` is true, 'members' will be a single doc as opposed to
    // an array. `justOne` is false by default.
    justOne: false,
    options: { sort: { name: -1 }, limit: 5 }
});

您使用的是什么版本的Mongoose?我知道排序语法在3.0中发生了很大的变化。我使用的是Mongoose 2.5.14。两天后我有一个重要的项目演示,所以我不会冒险更新我的堆栈。Mongoose在填充期间有排序问题,但尚未解决。请记住这一点。这是为什么答案预计起飞时间?