Bạn có thể coi chỉ mục trường đơn MongoDB như một mảng, với các con trỏ đến các vị trí tài liệu. Ví dụ:nếu bạn có một bộ sưu tập với (lưu ý rằng trình tự cố tình không theo thứ tự):
[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}
Chỉ mục một trường
Bây giờ nếu bạn làm:
db.collection.createIndex({a:1})
Chỉ số gần giống như sau:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Lưu ý ba điều quan trọng:
- Nó được sắp xếp theo
a
tăng dần - Mỗi mục nhập trỏ đến vị trí chứa các tài liệu liên quan
- Chỉ mục chỉ ghi lại các giá trị của
a
đồng ruộng.b
trường hoàn toàn không tồn tại trong chỉ mục
Vì vậy, nếu bạn thực hiện một truy vấn như:
db.collection.find().sort({a:1})
Tất cả những gì nó phải làm là xem chỉ mục từ trên xuống dưới, tìm nạp và xuất ra tài liệu mà các mục chỉ đến. Lưu ý rằng bạn cũng có thể xem chỉ mục từ phía dưới, ví dụ:
db.collection.find().sort({a:-1})
và sự khác biệt duy nhất là bạn đảo ngược chỉ mục.
Bởi vì b
hoàn toàn không có trong chỉ mục, bạn không thể sử dụng chỉ mục khi truy vấn bất kỳ điều gì về b
.
Chỉ số tổng hợp
Trong một chỉ mục kết hợp, ví dụ:
db.collection.createIndex({a:1, b:1})
Có nghĩa là bạn muốn sắp xếp theo a
đầu tiên, sau đó sắp xếp theo b
. Chỉ mục sẽ giống như sau:
[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1
Lưu ý rằng:
- Chỉ mục được sắp xếp từ
a
- Trong mỗi
a
bạn có mộtb
được sắp xếp - Bạn có 5 mục nhập chỉ mục so với chỉ có 3 mục trong ví dụ trường đơn trước đó
Sử dụng chỉ mục này, bạn có thể thực hiện một truy vấn như:
db.collection.find({a:2}).sort({b:1})
Nó có thể dễ dàng tìm thấy ở đâu a:2
sau đó đi bộ chỉ mục về phía trước. Với chỉ số đó, bạn không thể làm được :
db.collection.find().sort({b:1})
db.collection.find({b:1})
Trong cả hai truy vấn, bạn không thể dễ dàng tìm thấy b
vì nó trải rộng trên toàn bộ chỉ mục (nghĩa là không nằm trong các mục liền nhau). Tuy nhiên, bạn có thể làm:
db.collection.find({a:2}).sort({b:-1})
vì về cơ bản bạn có thể tìm thấy a:2
và đi bộ b
các mục nhập lùi lại.
Chỉnh sửa :làm rõ câu hỏi của @ marcospgp trong bình luận:
Khả năng sử dụng chỉ mục {a:1, b:1}
để đáp ứng find({a:2}).sort({b:-1})
thực sự có ý nghĩa nếu bạn nhìn thấy nó từ quan điểm bảng được sắp xếp. Ví dụ:chỉ mục {a:1, b:1}
có thể được coi là:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
find ({a:2}). sort ({b:1})
Chỉ mục {a:1, b:1}
có nghĩa là sort by a, then within each a, sort the b values
. Nếu sau đó bạn thực hiện find({a:2}).sort({b:1})
, chỉ mục biết vị trí của tất cả a=2
là. Trong khối a=2
này , b
sẽ được sắp xếp theo thứ tự tăng dần (theo đặc điểm chỉ mục), để truy vấn find({a:2}).sort({b:1})
có thể được hài lòng bởi:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2
find ({a:2}). sort ({b:-1})
Vì chỉ mục có thể được đi về phía trước hoặc phía sau, một quy trình tương tự đã được tuân theo, với một phần nhỏ ở cuối:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block backward to satisfy
2 | 2 <-- find({a:2}).sort({b:-1})
2 | 3 <--
3 | 1
3 | 2
Thực tế là chỉ mục có thể được tiến hoặc lùi là điểm quan trọng cho phép truy vấn find({a:2}).sort({b:-1})
để có thể sử dụng chỉ mục {a:1, b:1}
.
Giải thích công cụ lập kế hoạch truy vấn
Bạn có thể xem kế hoạch của trình lập kế hoạch truy vấn bằng cách sử dụng db.collection.explain().find(....)
. Về cơ bản nếu bạn thấy stage
trong tổng số COLLSCAN
, không có chỉ mục nào được sử dụng hoặc có thể được sử dụng cho truy vấn. Xem giải thích kết quả
để biết chi tiết về đầu ra của lệnh.