Thao tác với MongoDB index trong mongoose

MongoDB Indexs

Trong MongoDB index hỗ trợ thực hiện các câu truy vấn hiệu quả hơn. Nếu không có index, MongoDB sẽ phải duyệt tất cả các document trong một collection để tìm ra những document thoả mãn với điều kiện truy vấn. Nếu có một index tồn tại, MongoDB có thể sử dụng nó để giới hạn số lượng document mà nó phải kiểm tra.

Indexs là một cấu trúc đặc biết lưu trữ một phần nhỏ của collection, nó sẽ lưu giá trị của một field hoặc một tập các field được đánh index và sắp xếp chúng theo giá trị của field.

mongodb index

Với việc lưu trữ indexs và sắp xếp chúng, giúp MongoDB nhanh chóng tìm được khoảng mà nó cần tìm kiếm (khoảng xanh). Từ các index được tìm thấy có thể nhanh chóng truy xuất đến document được lưu trữ trong database MongoDB.

Các loại index trong MongoDB

MongoDB cung cấp một số loại index khác nhau để hỗ trợ cho các kiểu dữ liệu và câu truy vấn khác nhau.

Single Field

Index trên một field duy nhất. Mặc định MongoDB lập single field index trên _id.

Thứ tự sắp xếp index trong single field là không quan trọng vì mongodb có thể đi từ 2 hướng đầu đến cuối và ngược lại.

Compound index

MongoDB cũng hỗ trợ đánh index trên nhiều field. Lưu ý thứ tự của các field được đánh index điều có ý nghĩa. Ví dụ như compound index {name: 1, userid: -1}, đầu tiên MongoDB sẽ sắp sắp index theo name, sau đó với các name có cùng giá trị tiến hành sắp xếp theo userid.

compound index mongodb

Multikey index

MongoDB sử dụng multikey index để index các nội dung là array. Nếu bạn đánh index trên field là array thì MongoDB sẽ tạo các index riêng biệt cho tất cả các phần tử trong array.

Multikey index cho phéo truy vấn chọn các tài liệu bằng cách khớp với một hoặc nhiều phần tử trong array.

Lưu ý là Multikey index là tự mongodb thiết lập khi bạn đánh index trên field có kiểu dữ liệu array. Bạn không cần chỉ định bất cứ thứ gì.

Text index

Text index hỗ trợ tìm kiếm các nội dung có kiểu dữ liệu string trong collection. Text index không lưu trữ ngôn ngữ (vn, en etc) mà chỉ lưu các từ gốc.

Index Properties

Unique indexs

Unique index property đảm bảo bảo rằng sẽ không có giá trị trùng lặp trên các field được đánh chỉ mục unique.

Sparse Index

Sparse index chỉ lưu trữ các document có dữ liệu tại field được lập chỉ mục ngay cả khi nó có giá trị null. Nếu bạn không thêm field được đánh sparse index khi insert thì nó sẽ bỏ qua.

Bạn có thể kết hợp sparse index với unique index để ngăn chặn việc thêm dữ liệu trùng lặp và có thể bỏ qua khi field được index không được thêm vào khi insert.

Ví dụ trong mongoose:

const UserSchema = mongoose.Schema({
    email: {
        type: String,
        sparse: true,
        unique: true,
 });
await new UserModel().save()
await new UserModel().save()

or
await new UserModel({email: "email 1"}).save()
await new UserModel({email: "email 2"}).save()

Trường hợp dưới đây các bạn sẽ bị lỗi E11000 duplicate key error collection:

await new UserModel({email: null}).save()
await new UserModel({email: null}).save()

Như đã đề cập ở trên, sparse index sẽ lưu ngay cả khi giá trị là null. Nên khi bạn save() cả 2 User là null thì sẽ bị lỗi trùng lặp dữ liệu

TTL index

TTL index là một loại index đặc biệt trong MongoDB tự động xoá document trong collection sau một thời gian được định sẵn.  TTL index phù hợp cho các loại dữ liệu như event data, log, session.

Lưu ý TTL index chỉ hoạt động với những field có kiểu là Date.

Tạo index trong mongoose

Bạn có thể định nghĩa index tại field trong lúc định nghĩa Schema hoặc sử dụng Schema#index() để tạo index.

Tạo index tại field

  var animalSchema = new Schema({
    name: String,
    type: String,
    tags: { type: [String], index: true } // field level
  });

  animalSchema.index({ name: 1, type: -1 }); // index() method

Tạo index sử dụng Schema#index()

  var animalSchema = new Schema({
    name: String,
    type: String,
    tags: { type: [String] }
  });

  animalSchema.index({ name: 1, type: -1 }); // index() method

Sparse index trong mongoose

Sparse index trong mongoose thường được dùng chung với unique index để tránh việc trùng lặp dữ liệu.

Tạo spare index tại field level

var s = new Schema({ name: { type: String, sparse: true } });

Tạo spare index sử dụng Schema#index()

var s = new Schema({ name: String });
s.index({email: 1}, {sparse: true})

Unique index trong mongoose

Tạo unique index tại field level

var s = new Schema({ name: { type: String, unique: true }});

Tạo unique index sử dụng Schema#index()

var s = new Schema({ name: String });
s.index({email: 1}, {unique: true})

Text index trong mongoose

Tạo text index tại field level

var s = new Schema({name : {type: String, text : true });

Tạo text index sử dụng Schema#index()

Cách này mình khuyên dùng. Trong một số trường hợp cách trên sẽ bị lỗi. Các bạn có thể xem qua issues tại đây: https://github.com/Automattic/mongoose/issues/3824

var s = new Schema({name : String });
s.index({name: 'text'});

TTL index trong mongoose

Để tạo TTL index cho một field trong mongoose, field đó bắt buộc phải có kiểu Date. 

Tạp TTL index tại field level

const s = mongoose.Schema({
    expireAt: {
        type: Date,
        default: Date.now,
        expires: 60
    },
});

Tạo TTL index sử dung Schema#index()

const s = mongoose.Schema({
    expireAt: {
        type: Date,
        default: Date.now
    },
});

s.index({expireAt: 1}, {expires: 60});

Kết hợp unique và sparse index

var s = new Schema({ name: { type: String, unique: true, sparse: true }});

// or
var s = new Schema({ name: String });
s.index({email: 1}, {sparse: true, unique: true})

Các bạn sử dụng Schema#index() khi các bạn muốn đánh compound index, nếu không thì thường đánh index tại field là nhanh nhất.

Note: Các bạn cần phân biêt giữa loại index (single, compound etc.) với index property. Ví dụ bạn đánh index cho một field email trong UserSchema thì đó thuộc dạng single index, và bạn lại thêm một số index property nữa như unique, sparse thì index đó sẽ kiểm tra thêm tính trùng lặp khi nó lưu index và bỏ qua các dữ liệu thiếu các trường được index nhưng nó vẫn là single index.

Trong mongoose, khi bạn đánh dấu sparse : true hoặc unique true mặc định nó sẽ tạo index cho field đó và thêm sparse hoặc unique property tương ứng cho field.

4.8 5 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x