[英]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.