Javascript Mongoose,按填充字段对查询进行排序
据我所知,可以使用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
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在填充期间有排序问题,但尚未解决。请记住这一点。这是为什么答案预计起飞时间?