Giả sử rằng những gì bạn muốn sẽ là tất cả các tài liệu có giá trị "điểm" làm "khóa" trong mảng và sau đó sắp xếp theo "giá trị" cho "khóa" đó, thì điều này hơi nằm ngoài phạm vi .find()
phương pháp.
Lý do là nếu bạn đã làm điều gì đó như thế này
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })
Vấn đề là mặc dù các phần tử phù hợp do có khóa khớp là "point", không có cách nào để nói cái nào data.v
bạn đang đề cập đến cho loại. Ngoài ra, một sort
trong .find()
kết quả sẽ không giống như thế này:
db.collection.find({
"setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })
Mà sẽ là cố gắng để sử dụng toán tử vị trí trong một sắp xếp, về cơ bản cho biết phần tử nào sử dụng giá trị của v
trên. Nhưng điều này không được hỗ trợ và không có khả năng xảy ra, và để giải thích rất có thể, giá trị "chỉ mục" đó có thể sẽ khác nhau trong mọi tài liệu.
Nhưng loại chọn lọc này sắp xếp có thể được thực hiện bằng cách sử dụng .aggregate()
.
db.collection.aggregate([
// Actually shouldn't need the setid
{ "$match": { "data": {"$elemMatch": { "k": "points" } } } },
// Saving the original document before you filter
{ "$project": {
"doc": {
"_id": "$_id",
"setid": "$setid",
"date": "$date",
"version": "$version",
"data": "$data"
},
"data": "$data"
}}
// Unwind the array
{ "$unwind": "$data" },
// Match the "points" entries, so filtering to only these
{ "$match": { "data.k": "points" } },
// Sort on the value, presuming you want the highest
{ "$sort": { "data.v": -1 } },
// Restore the document
{ "$project": {
"setid": "$doc.setid",
"date": "$doc.date",
"version": "$doc.version",
"data": "$doc.data"
}}
])
Tất nhiên điều đó giả định là data
mảng chỉ có một yếu tố có các điểm chính. Nếu có nhiều hơn một, bạn cần phải $group
trước loại như thế này:
// Group to remove the duplicates and get highest
{ "$group": {
"_id": "$doc",
"value": { "$max": "$data.v" }
}},
// Sort on the value
{ "$sort": { "value": -1 } },
// Restore the document
{ "$project": {
"_id": "$_id._id",
"setid": "$_id.setid",
"date": "$_id.date",
"version": "$_id.version",
"data": "$_id.data"
}}
Vì vậy, có một cách sử dụng .aggregate()
để thực hiện một số phức tạp sắp xếp tài liệu và vẫn trả lại đầy đủ kết quả tài liệu gốc.
Đọc thêm về toán tử tổng hợp
và khuôn khổ chung. Đó là một công cụ hữu ích để tìm hiểu đưa bạn vượt ra ngoài .find()
.