Điều bạn có vẻ không hiểu ở đây là $exists
không thể "lấy" một chỉ mục theo bất kỳ cách nào, ngay cả khi thưa thớt. Như chính tài liệu đã nói:
Ví dụ được đưa ra trong các trang đó là { "$exists": false }
truy vấn. Nhưng điều kiện logic ngược lại không tạo ra sự khác biệt nào ở đây.
Để có được "lợi ích đầy đủ" của chỉ mục "thưa thớt" thì bạn cần phải xem xét "loại" dữ liệu mà nó lưu giữ và truy vấn một cách thích hợp.
Đối với số, một cái gì đó như:
db.collection.find({ "a": "foobar", "b": { "$gte": -9999, "$lte": 9999 } })
Cái nào sử dụng một chỉ mục và một cái thưa thớt. Hoặc đối với văn bản dựa trên:
db.collection.find({ "a": "foobar", "b": /.+/ })
Điều này cũng sẽ sử dụng chỉ mục thưa thớt và chỉ xem xét những chỉ mục mà "b" đã được xác định.
Đối với "mảng" thì "hãy cẩn thận". Vì giá trị đang được xem xét có thể là một trong những giá trị trên trừ khi bạn làm điều này:
db.collection.insert({ "a": 1, "b": [[]] })
Sau đó, điều này là ổn:
db.ab.find({ "a": 1, "b": { "$type": 4 } })
Nhưng sẽ không thực sự sử dụng chỉ mục "thưa thớt" vì những lý do tương tự $exists
sẽ không hoạt động ở đây.
Vì vậy, bạn cần hiểu các thuật ngữ ở đây có nghĩa là gì và "truy vấn một cách thích hợp" để sử dụng các định nghĩa chỉ mục mà bạn tạo nếu bạn mong đợi hiệu suất tối đa.
Đây là những ví dụ rõ ràng bạn có thể tự kiểm tra và xem kết quả là đúng. Tôi ước rằng tài liệu cốt lõi rõ ràng hơn về những điểm này, nhưng tôi cũng biết rằng nhiều người đã cố gắng đóng góp (và đã đưa ra những lời giải thích tuyệt vời) nhưng chưa có tài liệu nào trong số này được đưa vào cho đến nay.
Đoán đó là lý do tại sao bạn hỏi ở đây.