Trong MongoDB, cursor.sort()
phương thức chỉ định thứ tự mà truy vấn trả về các tài liệu phù hợp.
sort()
phương thức chấp nhận một tài liệu chỉ định trường để sắp xếp và thứ tự sắp xếp. Thứ tự sắp xếp có thể là 1
để tăng dần hoặc -1
để giảm dần.
Bạn cũng có thể chỉ định { $meta: "textScore" }
khi thực hiện $text
tìm kiếm, để sắp xếp theo textScore
được tính toán siêu dữ liệu theo thứ tự giảm dần.
Dữ liệu mẫu
Giả sử chúng ta có một bộ sưu tập có tên là pets
với các tài liệu sau:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 }
Sắp xếp theo thứ tự tăng dần
Để sắp xếp theo thứ tự tăng dần, chúng tôi sử dụng 1
cho thứ tự sắp xếp.
Dưới đây là ví dụ về truy vấn sử dụng $sort
toán tử để sắp xếp bộ sưu tập đó theo weight
trường theo thứ tự tăng dần.
db.pets.find().sort({ weight: 1 })
Kết quả:
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 }
Sắp xếp theo thứ tự giảm dần
Để sắp xếp theo thứ tự giảm dần, chúng tôi sử dụng -1
cho thứ tự sắp xếp.
db.pets.find().sort({ weight: -1 })
Kết quả:
{ "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
Sắp xếp theo nhiều trường
Để sắp xếp theo nhiều trường, hãy tách từng trường / tổ hợp thứ tự sắp xếp bằng dấu phẩy.
Ví dụ
db.pets.find().sort({ type: 1, weight: -1, _id: 1 })
Kết quả:
{ "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 }
Trong ví dụ này, chúng tôi sắp xếp theo loại type
trường theo thứ tự tăng dần trước, sau đó theo weight
trường theo thứ tự giảm dần, sau đó theo _id
trường theo thứ tự tăng dần.
Điều này có nghĩa là, nếu có nhiều vật nuôi cùng loại, những vật nuôi đó được sắp xếp theo weight
của chúng thứ tự giảm dần. Nếu có nhiều vật nuôi có cùng loại và trọng lượng thì những vật nuôi đó được sắp xếp theo _id
trường theo thứ tự tăng dần. Nếu chúng tôi không bao gồm _id
trong quá trình phân loại, thì những vật nuôi cùng loại và cùng trọng lượng có thể xuất hiện theo bất kỳ thứ tự nào. Điều này đúng mỗi khi chúng tôi chạy truy vấn. Không có trường sắp xếp trên một trường duy nhất (chẳng hạn như _id
), hoàn toàn có thể xảy ra (thậm chí có thể xảy ra) kết quả sẽ quay trở lại theo một thứ tự khác nhau mỗi khi truy vấn được chạy.
Sắp xếp các loại khác nhau
Khi so sánh các giá trị của các loại BSON khác nhau, MongoDB sử dụng thứ tự so sánh sau, từ thấp nhất đến cao nhất:
- MinKey (loại nội bộ)
- Không có
- Số (số nguyên, số dài, số đôi, số thập phân)
- Biểu tượng, Chuỗi
- Đối tượng
- Mảng
- BinData
- ObjectId
- Boolean
- Ngày tháng
- Dấu thời gian
- Cụm từ Thông dụng
- MaxKey (loại nội bộ)
Giả sử chúng ta có một bộ sưu tập được gọi là bài đăng với các tài liệu sau:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
Lưu ý rằng date
đầu tiên trường chứa chuỗi ngày tháng, trong khi hai tài liệu còn lại sử dụng đối tượng Ngày tháng.
Cũng lưu ý rằng chuỗi ngày chứa chính xác ngày tháng như trong tài liệu 3 và ngày này là một ngày muộn hơn so với ngày trong tài liệu 2.
Hãy sắp xếp theo date
các trường của các tài liệu đó:
db.posts.find().sort({ date: 1 }).pretty()
Kết quả:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
Trong trường hợp này, chúng tôi sắp xếp theo thứ tự tăng dần, có nghĩa là các ngày sớm hơn sẽ đến trước. Tuy nhiên, tài liệu đầu tiên của chúng tôi chứa một chuỗi ngày thay vì một đối tượng Ngày, và vì vậy, nó xuất hiện trước - ngay cả khi ngày của nó muộn hơn ngày trong tài liệu 2.
Đây lại là nó, nhưng theo thứ tự giảm dần:
db.posts.find().sort({ date: -1 }).pretty()
Kết quả:
{ "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Một lần nữa, các loại dữ liệu khác nhau được sắp xếp riêng trong chúng.
Sắp xếp siêu dữ liệu điểm văn bản
Bạn có thể sử dụng { $meta: "textScore" }
đối số để sắp xếp theo điểm mức độ liên quan giảm dần khi sử dụng $text
tìm kiếm.
Ví dụ
db.posts.find(
{ $text: { $search: "funny" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } }
).pretty()
Kết quả:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z"), "score" : 0.6666666666666666 } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z"), "score" : 0.6 } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z", "score" : 0.5833333333333334 }
Trong ví dụ này, chúng tôi sắp xếp theo { $meta: "textScore" }
.
Từ MongoDB 4.4, dòng chuyển đến { score: { $meta: "textScore" }}
Là tùy chọn. Bỏ qua điều này sẽ bỏ qua score
trường từ các kết quả. Do đó, chúng ta có thể làm như sau (từ MongoDB 4.4):
db.posts.find(
{ $text: { $search: "funny" } }
).sort({ score: { $meta: "textScore" } }
).pretty()
Kết quả:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Đang thực hiện $text
những tìm kiếm như thế này yêu cầu chúng tôi phải tạo một chỉ mục văn bản. Nếu không, một IndexNotFound
lỗi sẽ được trả lại.
Thông tin thêm
Xem tài liệu MongoDB để biết thêm thông tin.