Zdá se, že zde máte na mysli to, že chcete „seřadit“ své výsledky na základě „délky“ pole „odpovědí“, spíše než podle „vlastnosti“ zvané „délka“, jak naznačuje vaše syntaxe. Pro záznam, tato syntaxe by zde nebyla možná, protože váš model je "odkazovaný", což znamená, že jediným údajem přítomným v poli pole v dokumentech této kolekce je ObjectId
hodnoty těchto odkazovaných dokumentů.
Ale můžete to udělat pomocí .aggregate()
metoda a $size
operátor:
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
}
)
Agregační potrubí funguje po etapách. Za prvé, existuje $project
pro pole ve výsledcích, kde použijete $size
vrátí délku zadaného pole.
Nyní je zde pole s "délkou", postupujte podle kroků pomocí $sort
a $limit
které jsou aplikovány jako své vlastní fáze v rámci agregačního potrubí.
Lepším přístupem by bylo vždy udržovat vlastnost length vašeho pole „odpovědí“ v dokumentu. To usnadňuje třídění a dotazování bez dalších operací. Údržba je jednoduchá pomocí $inc
operátor jako vy $push
nebo $pull
položky z pole:
Question.findByIdAndUpdate(id,
{
"$push": { "answers": answerId },
"$inc": { "answerLength": 1 }
},
function(err,doc) {
}
)
Nebo naopak při odstraňování:
Question.findByIdAndUpdate(id,
{
"$pull": { "answers": answerId },
"$inc": { "answerLength": -1 }
},
function(err,doc) {
}
)
I když nepoužíváte atomické operátory, pak platí stejné principy, kde "délku" aktualizujete za pochodu. Pak je dotazování pomocí řazení jednoduché:
Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
});
Protože vlastnost je již v dokumentu uvedena.
Udělejte to buď pomocí .aggregate()
beze změn ve vašich datech nebo změňte data tak, aby vždy zahrnovala délku jako vlastnost a vaše dotazy budou velmi rychlé.