[英]Sorting by virtual field in mongoDB (mongoose)
假设我有一些 Schema,它有一个像这样的虚拟字段
var schema = new mongoose.Schema(
{
name: { type: String }
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
schema.virtual("name_length").get(function(){
return this.name.length;
});
在查询中是否可以按虚拟字段对结果进行排序? 就像是
schema.find().sort("name_length").limit(5).exec(function(docs){ ... });
当我尝试这个时,结果很简单,没有排序......
您将无法按虚拟字段排序,因为它们未存储到数据库中。
虚拟属性是便于使用但不会持久保存到mongodb的属性。
我不知道在聚合中重用现有虚拟的任何方法,但您可能能够在聚合阶段将虚拟投影到您的文档中。
我抽象了我最近构建的聚合管道。 想象一下,您有一组键,其中包含一组直接存储在团队文档中的玩家。 下面的管道将按照优先球员的排名对这些球队进行排序,其中优先球员基本上是一个虚拟财产,在某些情况下包含球队中最相关的球员(在这个例子中,我们只想考虑进攻和防守球员)。 在我们的案例中,这种情况有多种可能性,取决于用户的选择,因此无法在文档中持久化。
我们的“团队”文档非常大,并且由于投影文档仅在内存中可用,如果我们只添加一个字段并将团队集合的整个文档保存在内存中,那么它会带来巨大的性能成本。 因此我们只投影我们需要的那些字段,在限制结果后进行排序和恢复原始文档。
[
// find all teams from germany
{ '$match': { country: 'de' } },
// project to documents containing sort relevant fields
// and add field favoredPlayer per team
{ '$project': {
rank: 1,
'favoredPlayer': {
'$arrayElemAt': [
{
// remove players that should be ignored
$filter: {
input: '$players',
as: 'p',
cond: { $in: ['$$p.position', ['offense', 'defense']] },
},
},
// take first of the filtered players since players are already sorted by relevance in our db
0,
],
},
}},
// sort teams by the ranking of the favoredPlayer
{ '$sort': { 'favoredPlayer.ranking': -1, rank: -1 } },
{ '$limit': 10 },
// $lookup $unwind $replaceRoot to restore original database document
{ '$lookup': { from: 'teams', localField: '_id', foreignField: '_id', as: 'subdoc' } },
{ '$unwind': { path: '$subdoc' } },
{ '$replaceRoot': { newRoot: '$subdoc' } },
];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.