Như đã lưu ý, tôi hy vọng tài liệu của bạn thực sự có một mảng, nhưng nếu $ elemMatch đang hoạt động cho bạn thì chúng nên làm.
Ở bất kỳ mức độ nào, bạn không thể sắp xếp theo một phần tử trong mảng bằng cách sử dụng tìm. Nhưng có một trường hợp bạn có thể thực hiện việc này bằng cách sử dụng .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"
}}
])
Về cơ bản, sau khi thực hiện $ so khớp
điều kiện cho các tài liệu chứa kết quả phù hợp, sau đó bạn sử dụng $ project
"lưu trữ" tài liệu gốc trong _id
trường và $ unwind
"bản sao" của mảng "thực thể".
$ khớp
tiếp theo
"lọc" nội dung mảng để chỉ những nội dung có liên quan. Sau đó, bạn áp dụng $ sort
với các tài liệu "phù hợp".
Vì tài liệu "gốc" được lưu trữ trong _id
, bạn sử dụng $ project
để "khôi phục" cấu trúc mà tài liệu thực sự phải bắt đầu.
Đó là cách bạn "sắp xếp" trên phần tử phù hợp của một mảng.
Lưu ý rằng nếu bạn có nhiều "kết quả phù hợp" trong một mảng cho tài liệu mẹ, khi đó bạn sẽ phải sử dụng thêm $ nhóm
để nhận giá trị $ max cho trường "mức độ liên quan" để hoàn thành việc sắp xếp của bạn.