Index trong MongoDB
- 19-05-2026
- Toanngo92
- 0 Comments
Mục lục
Mục tiêu học tập
Trong session này, học viên sẽ học:
- Giải thích index
- Mô tả các loại index
- Liệt kê lợi ích của việc sử dụng index
- Giải thích cách tạo và xoá index
Trong một quyển sách, trang đầu tiên thường chứa mục lục liệt kê các chương, chủ đề và chủ đề con cùng số trang. Điều này giúp điều hướng đến một chương, chủ đề hoặc chủ đề con cụ thể trong sách thay vì phải lật qua toàn bộ các trang để tìm thông tin cần thiết.
Tương tự, index đóng vai trò như bộ chỉ mục cho database. Chúng giúp truy cập dữ liệu cần thiết trong thời gian ngắn với ít overhead hơn.
Session này sẽ giải thích về index và các loại index khác nhau trong MongoDB. Ngoài ra, session cũng sẽ giải thích lợi ích của việc sử dụng index. Cuối cùng, session sẽ giải thích cách tạo và xoá index.
7.1 Giới thiệu về Indexes
Indexes thực chất là các cấu trúc dữ liệu lưu trữ giá trị của một field hoặc nhiều field theo thứ tự tăng dần hoặc giảm dần.
Sau khi index được tạo, người dùng có thể dễ dàng query một document cụ thể với thời gian phản hồi thấp. Điều này là do database engine sử dụng index để tìm document cụ thể thay vì phải duyệt toàn bộ collection để xác định document cần tìm.
Việc này cải thiện hiệu suất query và giảm overhead của database engine khi phải duyệt qua toàn bộ collection.
Thứ tự của index giúp truy cập dữ liệu dễ dàng trong các query dựa trên equality và range.
Theo mặc định, MongoDB thêm field _id cho mỗi document trong collection. Field này là duy nhất cho từng document và ngăn chặn việc chèn document trùng lặp vào collection.
Một index được tạo mặc định trên field _id và không thể bị xoá. Nó được gọi là Default Index.
MongoDB hỗ trợ nhiều loại index khác nhau:
- Single field index
- Compound index
- Multikey index
- Text index
- Wildcard index
- Hashed index
7.2 Chỉ mục một trường
MongoDB cho phép người dùng tạo index trên một field duy nhất của document trong collection.
Field được tạo index phải là field quan trọng thường được dùng khi tìm kiếm document trong collection đó.
Index được tạo trên một field duy nhất được gọi là single field index.
Cú pháp tổng quát để tạo single field index là:
db.collection_name.createIndex(key, option, commitQuorum)
Lệnh createIndex nhận các tham số được mô tả trong Table 7.1.
| Parameter | Description |
|---|---|
| key | Là cặp key-value, trong đó key xác định field sẽ được tạo index và value xác định thứ tự của index. Giá trị 1 là thứ tự tăng dần và -1 là thứ tự giảm dần. Đây là tham số bắt buộc |
| option | Là document chứa các option xác định cách index được tạo. Đây là tham số tuỳ chọn |
| commitQuorum | Xác định số replica set chứa dữ liệu và tham gia voting phải phản hồi thành công việc tạo index trước khi primary đánh dấu index là sẵn sàng sử dụng. Đây là tham số tuỳ chọn |
Bảng 7.1: Tham số của lệnh createIndex
Tham số option trong lệnh createIndex nhận các tham số được mô tả trong Table 7.2.
| Parameter | Description |
|---|---|
| background | Giá trị boolean. Nếu đặt true, index sẽ được build ở background mà không ảnh hưởng đến các hoạt động database khác. Mặc định là false |
| unique | Giá trị boolean. Nếu đặt true, tạo unique index không cho phép chèn nhiều hơn một document có cùng index key. Mặc định là false |
| name | Giá trị string xác định tên cho index. Nếu không chỉ định, MongoDB sẽ gán tên là tổ hợp của tên field được index và thứ tự sắp xếp |
| sparse | Giá trị boolean. Nếu đặt true, chỉ các document có field được chỉ định mới được đưa vào index. Mặc định là false |
| expireAfterSeconds | Giá trị integer xác định thời gian tính bằng giây. Đây là TTL (Time-To-Live) kiểm soát thời gian document được giữ lại trong collection bởi MongoDB |
Bảng 7.2: Danh sách option để tạo Single Field Index
Để hiểu tầm quan trọng của indexing, trong database sample_analytics, hãy tìm document có account_id là 781775 trong collection grades.
Để xem chi tiết thực thi của query, sử dụng phương thức:
explain("executionStats")
Để thực hiện điều này, query cần chạy là:
db.accounts.find({"account_id":781775})
.explain("executionStats")

Figure 7.1 hiển thị output của query này.
Lưu ý rằng trong execution status, tổng số document được kiểm tra là 1746.
Bây giờ, hãy tạo index cho collection accounts trong database sample_analytics dựa trên field account_id theo thứ tự tăng dần.
Để thực hiện điều này, query cần chạy là:
db.accounts.createIndex({"account_id":1})
Index được tạo như được chỉ định trong query.
Bây giờ hãy chạy lại query trước đó.

Figure 7.2 hiển thị output của query.
Lưu ý rằng trong output, số lượng document được kiểm tra là 1.
Điều này cho thấy sau khi index được tạo, số document cần kiểm tra giảm xuống, từ đó giảm thời gian cần thiết để hoàn thành việc thực thi query.
Bây giờ, hãy tạo một index khác cho collection accounts dựa trên field limit theo thứ tự giảm dần.
Để thực hiện điều này, query cần chạy là:
db.accounts.createIndex({"limit":-1})
Index được tạo như được chỉ định trong query.
Để xem tất cả index đã được tạo cho collection accounts, chạy query:
db.accounts.getIndexes()

Figure 7.3 hiển thị output của query này.
Lưu ý rằng index trên field _id được tạo mặc định khi collection được tạo.
Hai index còn lại là user-created indexes.
7.3 Compound Index
Chỉ mục kết hợp
Trong MongoDB, người dùng có thể tạo index dựa trên nhiều field.
Những loại index này được gọi là compound indexes.
Người dùng có thể tạo index tham chiếu tối đa 32 field.
Đối với mỗi field, phải chỉ định thứ tự sắp xếp.
Cú pháp để tạo compound index là:
db.collections.createIndex({
fieldName1: ord1,
fieldName2: ord2,
...
})
Thứ tự các field được chỉ định trong cú pháp rất quan trọng để index hoạt động hiệu quả.
Các document sẽ được sắp xếp theo fieldName1, sau đó trong mỗi giá trị của fieldName1, document sẽ tiếp tục được sắp xếp theo fieldName2, và cứ như vậy.
Việc thay đổi thứ tự field trong lệnh createIndex sẽ tạo ra kết quả khác nhau về hiệu quả của index.
Trong database sample_training, giả sử người dùng muốn tạo compound index tên compoundIndex cho collection grades.
Index phải được tạo trước trên field class_id theo thứ tự tăng dần và sau đó trên field student_id theo thứ tự giảm dần.
Để thực hiện điều này, người dùng có thể chạy query:
db.grades.createIndex(
{class_id: 1, student_id:-1},
{name: "compoundIndex"}
)

Figure 7.4 hiển thị output của query này.
Để xem các index đã được tạo cho collection grades, chạy query:
db.grades.getIndexes()

Figure 7.5 hiển thị output của query này.
7.4 Multikey Index
Chỉ mục Multikey
Các index được tạo trên array field được gọi là multikey indexes.
Trong trường hợp này, index được tạo trên từng phần tử của array.
Multikey indexes hỗ trợ truy vấn hiệu quả các array trong document.
Cú pháp để tạo multikey index là:
db.collections.createIndex(arrayname : type)
Trong cú pháp:
arraynamexác định tên array field cần tạo indextypexác định thứ tự sắp xếp
Index không cần được chỉ định rõ là multikey index vì nếu field được chỉ định là array, MongoDB sẽ tự động tạo multikey index.
Xét collection accounts của database sample_analytics.
Người dùng muốn tạo multikey index tên multiKeyIndex trên field products, field này là một array, theo thứ tự tăng dần.
Để thực hiện điều này, người dùng có thể chạy query:
db.accounts.createIndex(
{products:1},
{name: "multiKeyIndex"}
)
Multikey index được tạo cho field products.
Để xem các index được tạo trên collection accounts, người dùng có thể thực hiện query:
db.accounts.getIndexes()

Figure 7.6 hiển thị output của query này.
7.4.1 Compound Multikey Index
Compound Multikey Index
Người dùng cũng có thể tạo compound multikey index.
Index này chỉ có thể có một array field làm indexed field.
Nếu document trong collection có hai array field A và B, index có thể bao gồm field A hoặc field B nhưng không thể bao gồm cả hai field cùng lúc.
Nếu một số document trong collection có field A là array và các document khác có field B là array, thì index có thể bao gồm cả hai field.
Nếu compound multikey index được tạo trên collection, bất kỳ document nào vi phạm index đều không thể được chèn vào collection.
Ví dụ, index được tạo để bao gồm field A tồn tại trong một số document, và field B tồn tại trong các document khác.
Trong trường hợp này, document chứa cả hai array field A và B sẽ không thể được chèn vào collection.
7.4.2 Index on Fields Embedded in Arrays
Index trên các field nhúng trong mảng
Một array field có thể chứa các field khác được nhúng bên trong nó.
Index có thể được tạo trên các embedded field này.
Trong database sample_training, collection grades có một array field tên scores.
Array này có các embedded field là type và score, như được hiển thị trong Figure 7.7.

Để tạo multikey index trên các field score.type và score.score, người dùng có thể thực hiện query:
db.grades.createIndex(
{"scores.type":1, "scores.score":1},
{name: "embeddedFieldIndex"}
)

Figure 7.8 hiển thị output của query này.
Các index được tạo trên field nhúng trong array giúp người dùng chạy query bao gồm một indexed field hoặc cả hai indexed field.
Ví dụ, người dùng có thể xem document mà scores.type là exam.
Để thực hiện điều này, query sử dụng là:
db.grades.find({ "scores.type": "exam" })
Người dùng cũng có thể xem document mà scores.type là quiz và scores.score lớn hơn 50.
Để thực hiện điều này, người dùng có thể chạy query:
db.grades.find({
"scores.type": "quiz",
"scores.score": { $gt: 50 }
})
Index cũng có thể được dùng để sắp xếp dữ liệu.
Giả sử người dùng muốn xem document mà scores.type là exam và sắp xếp scores.score cho từng loại giá trị theo thứ tự tăng dần.
Người dùng có thể chạy query:
db.grades.find({ "scores.type": "exam" })
.sort({ "scores.score": 1 })
7.5 Text Index
Chỉ mục văn bản
MongoDB cho phép người dùng tạo index trên text hoặc string.
Những loại index này được gọi là text indexes.
Text index có thể được tạo trên text field hoặc array của text element và hỗ trợ thực thi các text-based searches.
Một document chỉ có thể có một text index, nhưng index đó có thể bao gồm nhiều field.
Cú pháp tạo text index là:
db.collections.createIndex(key, options, commitQuorum)
Trong cú pháp này:
keyxác định tên field sẽ được tạo indexoptionxác định cách index được tạocommitQuorumxác định số lượng replica set nhỏ nhất phải báo thành công việc tạo index trước khi index được đánh dấu sẵn sàng sử dụng
Tham số option nhận nhiều tham số khác nhau như được mô tả trong Table 7.3.
| Parameter | Description |
|---|---|
| weights | Là document nhận giá trị từ 1 đến 99999. Các giá trị này biểu thị mức độ quan trọng của indexed field so với các field khác về mặt score |
| default_language | Giá trị string xác định ngôn ngữ dùng để xác định các quy tắc stemmer và tokenizer cũng như danh sách stop words. Mặc định là English |
| language_override | Giá trị string xác định ngôn ngữ dùng để override default language. Mặc định tham số này là language |
| textIndexVersion | Giá trị integer tuỳ chọn dùng để chỉ định version number cho index. Nếu tham số này được dùng, version number chỉ định sẽ thay thế default version number của index |
Bảng 7.3: Danh sách option để tạo Text Index
Xét collection inspections của database sample_training.
Người dùng muốn tạo text index trên field business_name.
Để thực hiện điều này, người dùng có thể chạy query:
db.inspections.createIndex({"business_name":1})
7.6 Wildcard Index
Chỉ mục Wildcard
Khi tạo các loại index khác nhau đã được thảo luận trước đó, field mà index sẽ được tạo phải được chỉ định làm tham số trong lệnh createIndex.
Tuy nhiên, do MongoDB cho phép schema linh hoạt hoặc phi cấu trúc, có thể xảy ra trường hợp tất cả document không có các field giống nhau để index được tạo.
Trong các trường hợp như vậy, wildcard indexes được tạo.
Wildcard indexes có thể được tạo trên:
- Unknown fields
- Unstructured schema
7.6.1 Wildcard Index on a Specific Field
Wildcard Index trên một field cụ thể
Cú pháp tạo wildcard index trên một field cụ thể là:
db.collections.createIndex({"fieldA.$**" : 1})
Cú pháp này dùng để tạo index trên tất cả giá trị trong field fieldA.
Nếu field này là document hoặc array, index sẽ duyệt qua document hoặc array và tạo index cho từng field trong document hoặc array.
Ví dụ, collection inspections trong database sample_training chứa field address, field này có nested field như city, zip, street và number như được hiển thị trong Figure 7.9.

Để tạo index trên field address, query sử dụng là:
db.inspections.createIndex({ "address.$**" : 1 })
Index này hiện có thể hỗ trợ các query như:
db.inspections.find({ "address.city" : "NEW YORK" })
db.inspections.find({ "address.zip" : {$gt:10029} })
7.6.2 Wildcard Index on All Fields
Wildcard Index trên tất cả field
Cú pháp tạo wildcard index trên tất cả field trong document là:
db.collection.createIndex({ "$**" : 1 })
Cú pháp này dùng để tạo index trên tất cả field của document trong collection được chỉ định.
Nếu field là document hoặc array, index sẽ duyệt qua document hoặc array và tạo index cho từng field trong document hoặc array.
Ví dụ, để tạo index trên tất cả field trong collection inspections, người dùng có thể chạy query:
db.inspections.createIndex({ "$**" : 1 })
7.6.3 Wildcard Indexes Including or Excluding Multiple Fields
Wildcard Index bao gồm hoặc loại trừ nhiều field
Người dùng có thể chỉ định nhiều field để indexing khi tạo wildcard indexes.
Cú pháp để tạo loại wildcard index này là:
db.collection.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"fieldA" : 1,
"fieldB.fieldC" : 1
}
}
)
Trong cú pháp này, fieldA và fieldB.fieldC là các field được chỉ định mà index sẽ được tạo trên đó.
Ví dụ, với collection transactions của database sample_analytics, người dùng muốn tạo index trên tất cả giá trị trong các field name và customer.gender.
Người dùng có thể chạy query:
db.sales.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"name" : 1,
"customer.gender" : 1
}
}
)
Tương tự, người dùng có thể chỉ định nhiều field không được bao gồm trong index khi tạo wildcard indexes.
Cú pháp tạo loại wildcard index này là:
db.collection.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"fieldA" : 0,
"fieldB.fieldC" : 0
}
}
)
Trong cú pháp này, fieldA và fieldB.fieldC là các field được chỉ định sẽ không được bao gồm trong index.
Ví dụ, đối với collection grades, để tạo index trên tất cả giá trị ngoại trừ các giá trị trong field class_id và scores.score, người dùng có thể chạy query:
db.grades.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"class_id" : 0,
"scores.score" : 0
}
}
)
7.7 Hashed Index
Chỉ mục Hashed
Hashing là quá trình sử dụng thuật toán để tính toán hash value cho từng giá trị trong field được chỉ định để indexing.
Hashed index được tạo bằng các hashed value này.
Hashed index không thể được tạo cho array field hoặc document field.
Cú pháp tạo hashed index là:
db.collections.createIndex({fieldname: "hashed"})
Ví dụ, để tạo hashed index cho field student_id của collection grades trong database sample_training, người dùng có thể chạy query:
db.inspections.createIndex({student_id: "hashed"})
Hashed indexes cũng có thể được bao gồm trong compound indexes.
Cú pháp tạo compound index với hashed index là:
db.collections.createIndex({
"fieldA" : 1,
"fieldB" : "hashed",
"fieldC" : -1
})
Giả sử người dùng muốn tạo compound index với hashed index cho collection grades.
Index phải sắp xếp field student_id theo thứ tự tăng dần, hash field class_id, và sắp xếp field scores theo thứ tự giảm dần.
Người dùng có thể chạy query:
db.inspections.createIndex({
"student_id" : 1,
"class_id" : "hashed",
"scores" : -1
})
Hashed indexes được sử dụng rất nhiều trong database sharding.
7.8 Drop Indexes
Xoá chỉ mục
Các index đã tạo có thể được xoá bằng lệnh dropIndexes.
Cú pháp của lệnh dropIndexes là:
db.collection.dropIndexes({indexes})
Tham số indexes xác định index hoặc các index sẽ bị xoá.
Nếu tham số này bị bỏ qua, tất cả index được tạo cho collection chỉ định sẽ bị xoá ngoại trừ default index được tạo trên field _id.
Để xoá các index được tạo trên collection inspection_collection trong database sample_training, trước tiên hãy xem các index đã tạo bằng query:
db.inspections.getIndexes()

Figure 7.10 hiển thị output của query này.
Để xoá ascending index được tạo trên field business_name, người dùng có thể chạy query:
db.inspections.dropIndexes("business_name_1")
MongoDB sẽ xoá index được chỉ định.
Để xoá nhiều index khỏi collection inspections, cần truyền một array chứa tên các index cần xoá vào lệnh dropIndexes.
Để thực hiện điều này, người dùng có thể chạy query:
db.inspections.dropIndexes([
"address.$**_1",
"$**_1"
])
Để xem các index còn lại trong collection inspections, người dùng có thể chạy query:
db.inspections.getIndexes()

Figure 7.11 hiển thị output của query này.
Để xoá tất cả index được tạo cho collection inspections, người dùng có thể chạy query:
db.inspections.dropIndexes()
Để xem các index còn lại trong collection inspections, người dùng có thể chạy query:
db.inspections.getIndexes()

Figure 7.12 hiển thị output của query này.
