Zoals opgemerkt hoop ik dat uw documenten daadwerkelijk een array hebben, maar als $elemMatch voor u werkt, dan zouden ze dat ook moeten doen.
Je kunt in ieder geval niet sorteren op een element in een array met behulp van find. Maar er is een geval waarin u dit kunt doen met .aggregate()
:
db.collection.aggregate([
// Match the documents that you want, containing the array
{ "$match": {
"nlp.entities": {
"$elemMatch": {
"text": "Neelie Kroes",
"type": "Person"
}
}
}},
// Project to "store" the whole document for later, duplicating the array
{ "$project": {
"_id": {
"_id": "$_id",
"url": "$url",
"nlp": "$nlp"
},
"entities": "$nlp.entities"
}},
// Unwind the array to de-normalize
{ "$unwind": "$entities" },
// Match "only" the relevant entities
{ "$match": {
"entities.text": "Neelie Kroes",
"entities.type": "Person"
}},
// Sort on the relevance
{ "$sort": { "entities.relevance": -1 } },
// Restore the original document form
{ "$project": {
"_id": "$_id._id",
"url": "$_id.url",
"nlp": "$_id.nlp"
}}
])
Dus in wezen, na het doen van de $match
voorwaarde voor documenten die de relevante overeenkomst bevatten, gebruikt u vervolgens $project
"bewaar" het originele document in de _id
field en $unwind
een "kopie" van de array "entiteiten".
De volgende $match
"filtert" de array-inhoud naar alleen die die relevant zijn. Dan pas je de $sort
toe
naar de "gematchte" documenten.
Aangezien het "originele" document werd opgeslagen onder _id
, gebruik je $project
om de structuur te "herstellen" waarmee het document eigenlijk moest beginnen.
Dat is hoe u "sorteert" op uw overeenkomende element van een array.
Merk op dat als je had meerdere "overeenkomsten" binnen een array voor een bovenliggend document, dan zou je een extra $group
om de $max-waarde voor het veld "relevantie" te krijgen om uw sortering te voltooien.