Wenn Sie Ergebnisse nach bestimmten Kriterien "gewichten" oder irgendeine Art von "berechnetem Wert" innerhalb einer "Sortierung" haben möchten, dann benötigen Sie die .aggregate()
Methode statt. Dadurch können "projizierte" Werte in $sort
verwendet werden Operation, für die nur ein vorhandenes Feld im Dokument verwendet werden kann:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Hier das $setIsSubset
-Operator ermöglicht den Vergleich des "ungelesenen" Arrays mit einem konvertierten Array von [userId]
um zu sehen, ob es Übereinstimmungen gibt. Das Ergebnis ist entweder true
wo die userId existiert oder false
wo nicht.
Diese kann dann an $sort
übergeben werden , das die Ergebnisse bevorzugt nach den Übereinstimmungen sortiert ( absteigende Sortierung ist true
oben ) und schließlich $limit
gibt nur die Ergebnisse bis zum angegebenen Betrag zurück.
Um also einen berechneten Begriff für "Sortieren" zu verwenden, muss der Wert in das Dokument "projiziert" werden, damit es sortiert werden kann. Mit dem Aggregations-Framework machen Sie das.
Beachten Sie auch, dass $elemMatch
ist nicht erforderlich, um nur einen einzelnen Wert innerhalb eines Arrays abzugleichen, und Sie müssen den Wert nur direkt angeben. Sein Zweck besteht darin, dass "mehrere" Bedingungen für ein einzelnes Array-Element erfüllt werden müssen, was hier natürlich nicht zutrifft.