Som nämnts hoppas jag att dina dokument faktiskt har en array, men om $elemMatch fungerar för dig så borde de göra det.
Du kan i alla fall inte sortera efter ett element i en array med hjälp av find. Men det finns ett fall där du kan göra detta med .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 huvudsak, efter att ha gjort $match
villkor för dokument som innehöll den relevanta matchningen använder du sedan $projekt
"lagra" originaldokumentet i _id
field och $unwind
en "kopia" av "entities"-arrayen.
Nästa $match
"filtrerar" arrayinnehållet till endast de som är relevanta. Sedan använder du $sort
till de "matchade" dokumenten.
Eftersom det "original" dokumentet lagrades under _id
, använder du $project
för att "återställa" strukturen som dokumentet faktiskt hade till att börja med.
Det är så du "sorterar" på ditt matchade element i en array.
Observera att om du hade flera "matchningar" inom en array för ett överordnat dokument, då skulle du behöva använda ytterligare en $group
steg för att få $max-värdet för "relevans"-fältet för att slutföra sorteringen.