Wat u hier lijkt te bedoelen, is dat u uw resultaten wilt "sorteren" op basis van de "lengte" van de "antwoorden" -array, in plaats van een "eigenschap" genaamd "lengte", zoals uw syntaxis impliceert. Voor de goede orde, die syntaxis zou hier onmogelijk zijn omdat er naar uw model wordt verwezen, wat betekent dat de enige gegevens die aanwezig zijn in het arrayveld in de documenten van deze verzameling de ObjectId
zijn waarden van die documenten waarnaar wordt verwezen.
Maar u kunt dit doen met de .aggregate()
methode en de $size
operator:
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
}
)
Een aggregatiepijplijn werkt in fasen. Ten eerste is er een $project
voor de velden in de resultaten, waar u $size
. gebruikt om de lengte van de opgegeven array te retourneren.
Nu is er een veld met de "lengte", je volgt de fasen met $sort
en $limit
die worden toegepast als hun eigen fasen binnen een aggregatiepijplijn.
Een betere benadering zou zijn om altijd de eigenschap length van uw "antwoorden" -array in het document te behouden. Dit maakt het gemakkelijk om te sorteren en op te vragen zonder andere handelingen. Het onderhouden hiervan is eenvoudig met behulp van de $inc
operator als jij $push
of $pull
items uit de array:
Question.findByIdAndUpdate(id,
{
"$push": { "answers": answerId },
"$inc": { "answerLength": 1 }
},
function(err,doc) {
}
)
Of omgekeerd bij het verwijderen:
Question.findByIdAndUpdate(id,
{
"$pull": { "answers": answerId },
"$inc": { "answerLength": -1 }
},
function(err,doc) {
}
)
Zelfs als u de atomaire operatoren niet gebruikt, zijn dezelfde principes van toepassing wanneer u de "lengte" bijwerkt terwijl u doorgaat. Dan is opvragen met een sortering eenvoudig:
Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
});
Omdat de woning al in het document staat.
Dus doe het ofwel met .aggregate()
zonder wijzigingen in uw gegevens, of verander uw gegevens om altijd de lengte als eigenschap op te nemen en uw zoekopdrachten zullen zeer snel zijn.