MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

MongoDB $ sort

Trong MongoDB, $sort giai đoạn đường ống tổng hợp sắp xếp tất cả các tài liệu đầu vào và trả chúng về đường ống theo thứ tự đã sắp xếp.

Cú pháp

Cú pháp như sau:

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

Nơi <sort order> có thể là 1 để tăng dần, -1 để giảm dần hoặc { $meta: "textScore" } để 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.aggregate([
    { $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.aggregate([
    { $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.aggregate([
    { $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:

  1. MinKey (loại nội bộ)
  2. Không có
  3. Số (số nguyên, số dài, số đôi, số thập phân)
  4. Biểu tượng, Chuỗi
  5. Đối tượng
  6. Mảng
  7. BinData
  8. ObjectId
  9. Boolean
  10. Ngày tháng
  11. Dấu thời gian
  12. Cụm từ Thông dụng
  13. 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 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...",
	"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 áp dụng $sort đến ngày type các trường của các tài liệu đó:

db.posts.aggregate([
    { $sort: { date: 1 } } 
]).pretty()

Kết quả:

{
	"_id" : 1,
	"title" : "Web",
	"body" : "Create a 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...",
	"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.aggregate([
    { $sort: { date: -1 } } 
]).pretty()

Kết quả:

{
	"_id" : 3,
	"title" : "Oceans",
	"body" : "Oceans are wide and vast...",
	"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 website with these three easy steps...",
	"date" : "2021-01-01T00:00:00.000Z"
}

Một lần nữa, thứ tự ngày đã hết, do các loại dữ liệu khác nhau.

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.aggregate(
   [
     { $match: { $text: { $search: "funny" } } },
     { $sort: { score: { $meta: "textScore" }, title: -1 } }
   ]
).pretty()

Kết quả:

{
	"_id" : 2,
	"title" : "Animals",
	"body" : "Animals are funny things...",
	"date" : ISODate("2020-01-01T00:00:00Z")
}

Trong trường hợp này, chỉ một tài liệu phù hợp với truy vấn của chúng tôi.

Trong ví dụ này, chúng tôi sắp xếp theo { $meta: "textScore" } , rồi đến title thứ tự giảm dần. Chúng tôi đã sử dụng score dưới dạng tên trường tùy ý, nhưng điều này bị hệ thống truy vấn bỏ qua.

Đ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.

Sắp xếp kết quả theo nhóm

Quay lại với pets của chúng tôi bộ sưu tập, chúng ta có thể sử dụng $sort giai đoạn sau $group giai đoạn sắp xếp một nhóm tài liệu theo số lượng giá trị trong một trường cụ thể.

db.pets.aggregate([
    {
      $match: { weight: { $lt: 30 } }
    },
    {
      $group: { _id: "$type", count: { $sum: 1 } }
    },
     { 
      $sort : { count : -1 } 
    }
])

Kết quả:

{ "_id" : "Cat", "count" : 3 }
{ "_id" : "Dog", "count" : 2 }

Tuy nhiên, bạn có thể tốt hơn bằng cách sử dụng $sortByCount trong những trường hợp như vậy.

Thông tin thêm

Xem tài liệu MongoDB để biết thêm thông tin.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Sử dụng bản sao lưu để khắc phục các tình huống lỗi thường gặp cho MongoDB

  2. MongoDB:Lỗi nghiêm trọng:Không tìm thấy lớp 'MongoClient'

  3. MongoDB $ ReplaceAll

  4. Mongo tìm các bản sao cho các mục nhập cho hai hoặc nhiều trường

  5. Làm cách nào để sử dụng một biến làm tên trường trong mongodb-native findOne ()?