Ce que vous semblez vouloir dire ici, c'est que vous voulez "trier" vos résultats en fonction de la "longueur" du tableau "réponses", plutôt qu'une "propriété" appelée "longueur" comme l'implique votre syntaxe. Pour mémoire, cette syntaxe serait impossible ici car votre modèle est "référencé", ce qui signifie que les seules données présentes dans le champ de tableau dans les documents de cette collection sont le ObjectId
valeurs de ces documents référencés.
Mais vous pouvez le faire en utilisant .aggregate()
méthode et la $size
opérateur :
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
}
)
Un pipeline d'agrégation fonctionne par étapes. Tout d'abord, il y a un $project
pour les champs dans les résultats, où vous utilisez $size
pour renvoyer la longueur du tableau spécifié.
Maintenant il y a un champ avec la "longueur", vous suivez les étapes avec $sort
et $limit
qui sont appliqués comme leurs propres étapes dans un pipeline d'agrégation.
Une meilleure approche serait de toujours conserver la propriété length de votre tableau "réponses" dans le document. Cela facilite le tri et la recherche sans autres opérations. Le maintien de ceci est simple en utilisant le $inc
opérateur comme vous $push
ou $pull
éléments du tableau :
Question.findByIdAndUpdate(id,
{
"$push": { "answers": answerId },
"$inc": { "answerLength": 1 }
},
function(err,doc) {
}
)
Ou l'inverse lors de la suppression :
Question.findByIdAndUpdate(id,
{
"$pull": { "answers": answerId },
"$inc": { "answerLength": -1 }
},
function(err,doc) {
}
)
Même si vous n'utilisez pas les opérateurs atomiques, les mêmes principes s'appliquent lorsque vous mettez à jour la "longueur" au fur et à mesure. Ensuite, interroger avec un tri est simple :
Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
});
Comme la propriété est déjà présente dans le document.
Alors faites-le avec .aggregate()
sans modifier vos données, ou modifiez vos données pour toujours inclure la longueur en tant que propriété et vos requêtes seront très rapides.