Som nævnt håber jeg, at dine dokumenter faktisk har et array, men hvis $elemMatch virker for dig, så burde de.
I hvert fald kan du ikke sortere efter et element i en matrix ved hjælp af find. Men der er et tilfælde, hvor du kan gøre dette ved at bruge .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"
}}
])
Så i det væsentlige efter at have udført $match
betingelse for dokumenter, der indeholdt det relevante match, bruger du derefter $projekt
"gem" det originale dokument i _id
felt og $unwind
en "kopi" af "entities"-arrayet.
Den næste $match
"filtrerer" array-indholdet til kun dem, der er relevante. Derefter anvender du $sort
til de "matchede" dokumenter.
Da det "originale" dokument blev gemt under _id
, bruger du $project
for at "gendanne" den struktur, som dokumentet faktisk havde til at begynde med.
Det er sådan du "sorterer" på dit matchede element i et array.
Bemærk, at hvis du havde flere "matches" i et array for et overordnet dokument, så skulle du bruge en ekstra $group
trin for at få $max-værdien for "relevans"-feltet for at fuldføre din sortering.