Tối ưu truy vấn mảng lồng object với $elemMatch và Multikey Index
$elemMatch cho phép khớp nhiều điều kiện trên cùng một phần tử trong mảng, kết hợp với Multikey Index để tăng tốc độ truy vấn.
1. Dữ liệu mẫu
> db.demo444.insertOne({ Information: [{ id: 1, Name: "Chris" }] });
> db.demo444.insertOne({ Information: [{ id: 2, Name: "David" }] });
> db.demo444.insertOne({ Information: [{ id: 3, Name: "Bob" }] });
2. Tạo Multikey Index (quan trọng!)
> db.demo444.createIndex({ "Information.id": 1, "Information.Name": 1 });
3. Truy vấn với $elemMatch
> db.demo444.find({
Information: {
$elemMatch: { id: 2, Name: "David" }
}
})
4. Kết quả
{ "_id": ObjectId("5e78ea87bbc41e36cc3caec0"), "Information": [{ "id": 2, "Name": "David" }] }
Tại sao cần $elemMatch?
Nếu dùng truy vấn thông thường:
// SAI - khớp nếu CÓ id=2 VÀ CÓ Name="David" (có thể ở 2 phần tử khác nhau)
db.demo444.find({ "Information.id": 2, "Information.Name": "David" })
$elemMatch đảm bảo cả hai điều kiện trên cùng một object trong mảng.
Multikey Index hoạt động như thế nào?
- MongoDB tạo index entry cho từng phần tử trong mảng
- Index trên
Information.idsẽ có 3 entry: 1, 2, 3 - Index compound
{ "Information.id": 1, "Information.Name": 1 }cho phép lọc hiệu quả cả hai trường
Kiểm tra index được dùng
db.demo444.find({ Information: { $elemMatch: { id: 2, Name: "David" } } }).explain("executionStats")
Nhìn "winningPlan.stage": "IXSCAN" để xác nhận dùng index.