Ý bạn muốn nói ở đây là bạn muốn "sắp xếp" kết quả của mình dựa trên "độ dài" của mảng "câu trả lời", chứ không phải "thuộc tính" được gọi là "độ dài" như cú pháp của bạn ngụ ý. Đối với bản ghi, cú pháp đó sẽ không thể xảy ra ở đây vì mô hình của bạn là "được tham chiếu", có nghĩa là dữ liệu duy nhất hiện diện trong trường mảng trong tài liệu của bộ sưu tập này là ObjectId
giá trị của các tài liệu được tham chiếu đó.
Nhưng bạn có thể thực hiện việc này bằng cách sử dụng .aggregate ()
và $ size
nhà điều hành:
Question.aggregate(
[
{ "$project": {
"title": 1,
"content": 1,
"created": 1,
"updated": 1,
"author": 1,
"answers": 1,
"length": { "$size": "$answers" }
}},
{ "$sort": { "length": -1 } },
{ "$limit": 5 }
],
function(err,results) {
// results in here
}
)
Một đường ống tổng hợp hoạt động theo từng giai đoạn. Đầu tiên, có một $ project
cho các trường trong kết quả, nơi bạn sử dụng $ size
để trả về độ dài của mảng đã chỉ định.
Bây giờ có một trường với "length", bạn làm theo các giai đoạn với $ sort
và $ limit
được áp dụng như các giai đoạn riêng của chúng trong một quy trình tổng hợp.
Một cách tiếp cận tốt hơn sẽ là luôn duy trì thuộc tính độ dài của mảng "câu trả lời" của bạn trong tài liệu. Điều này giúp bạn dễ dàng sắp xếp và truy vấn mà không cần thực hiện các thao tác khác. Duy trì điều này rất đơn giản bằng cách sử dụng $ inc
toán tử như bạn $ push
hoặc $ pull
các mục từ mảng:
Question.findByIdAndUpdate(id,
{
"$push": { "answers": answerId },
"$inc": { "answerLength": 1 }
},
function(err,doc) {
}
)
Hoặc ngược lại khi loại bỏ:
Question.findByIdAndUpdate(id,
{
"$pull": { "answers": answerId },
"$inc": { "answerLength": -1 }
},
function(err,doc) {
}
)
Ngay cả khi bạn không sử dụng các toán tử nguyên tử, thì các nguyên tắc tương tự sẽ áp dụng khi bạn cập nhật "độ dài" khi bạn thực hiện. Sau đó, truy vấn với một sắp xếp rất đơn giản:
Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {
});
Vì thuộc tính đã có trong tài liệu.
Vì vậy, hãy làm điều đó với .aggregate ()
mà không có thay đổi nào đối với dữ liệu của bạn hoặc thay đổi dữ liệu của bạn thành luôn bao gồm độ dài dưới dạng thuộc tính và các truy vấn của bạn sẽ rất nhanh.