Това, което изглежда имате предвид тук, е, че искате да "сортирате" вашите резултати въз основа на "дължината" на масива "отговори", а не на "свойство", наречено "дължина", както предполага вашият синтаксис. За протокола, този синтаксис би бил невъзможен тук, тъй като вашият модел е "препратен", което означава, че единствените данни, налични в полето на масива в документите на тази колекция, са ObjectId
стойности на тези референтни документи.
Но можете да направите това с помощта на .aggregate()
метод и $size
оператор:
Question.aggregate(
[
{ "$project": {
"title": 1,
"content": 1,
"created": 1,
"updated": 1,
"author": 1,
"answers": 1,
"length": { "$size": "$answers" }
}},
{ "$sort": { "length": -1 } },
{ "$limit": 5 }
],
function(err,results) {
// results in here
}
)
Конвейерът за агрегиране работи на етапи. Първо, има $project
за полетата в резултатите, където използвате $size
за да върне дължината на посочения масив.
Сега има поле с „дължина“, следваш етапите с $sort
и $limit
които се прилагат като свои собствени етапи в конвейер за агрегиране.
По-добър подход би бил винаги да поддържате свойството дължина на вашия масив "отговори" в документа. Това улеснява сортирането и заявките без други операции. Поддържането на това е лесно с помощта на $incкод>
оператор като $push
или $pull
елементи от масива:
Question.findByIdAndUpdate(id,
{
"$push": { "answers": answerId },
"$inc": { "answerLength": 1 }
},
function(err,doc) {
}
)
Или обратното при премахване:
Question.findByIdAndUpdate(id,
{
"$pull": { "answers": answerId },
"$inc": { "answerLength": -1 }
},
function(err,doc) {
}
)
Дори и да не използвате атомарните оператори, тогава се прилагат същите принципи, когато актуализирате "дължината", докато вървите. Тогава заявката със сортиране е проста:
Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
});
Тъй като свойството вече е там в документа.
Така че или го направете с .aggregate()
без промени в данните ви или променете данните си така, че винаги да включват дължината като свойство и вашите заявки ще бъдат много бързи.