Tổng quan về truy vấn có bộ lọc phạm vi và bất đẳng thức trên nhiều trường

Cloud Firestore hỗ trợ sử dụng các bộ lọc phạm vi và bất đẳng thức trên nhiều trường trong một truy vấn. Giờ đây, bạn có thể có điều kiện về phạm vi và điều kiện không bằng nhau trên nhiều trường, đồng thời đơn giản hoá quá trình phát triển ứng dụng bằng cách uỷ quyền triển khai logic sau lọc cho Cloud Firestore.

Bộ lọc phạm vi và bất đẳng thức trên nhiều trường

Truy vấn sau đây trả về tất cả người dùng có độ tuổi lớn hơn 35 và chiều cao từ 60 đến 70 bằng cách sử dụng các bộ lọc phạm vi theo độ tuổi và chiều cao.

Mô-đun phiên bản web 9

  const q = query(
      collection(db, "users"),
      where('age', '>', 35),
      where('height', '>', 60),
      where('height', '<', 70)
    );

Swift

 let query = db.collection("users")
   .whereField("age", isGreaterThan: 35)
   .whereField("height", isGreaterThan: 60)
   .whereField("height", isLessThan: 70)

Objective-C

 FIRQuery *query = 
  [[[[self.db collectionWithPath:@"users"]
 queryWhereField:@"age" isGreaterThan:@35]
    queryWhereField:@"height" isGreaterThan:@60] 
        queryWhereField:@"height" isLessThan:@70];

Android Java

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin+KTX cho Android

 val query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70)

Java

  db.collection("users")
    .whereGreaterThan("age", 35)
    .whereGreaterThan("height", 60)
    .whereLessThan("height", 70);

Node.js

db.collection("users")
  .where('age', '>', 35),
  .where('height', '>', 60),
  .where('height', '<', 70)

Những điều cần cân nhắc khi lập chỉ mục

Trước khi bắt đầu chạy các truy vấn, hãy đảm bảo bạn đã đọc về truy vấnmô hình dữ liệu của Cloud Firestore.

Trong Cloud Firestore, mệnh đề ORDER BY của truy vấn sẽ xác định những chỉ mục có thể dùng để phân phát truy vấn. Ví dụ: truy vấn ORDER BY a ASC, b ASC yêu cầu chỉ mục tổng hợp trên các trường a ASC, b ASC.

Để tối ưu hoá hiệu suất và chi phí của các truy vấn trên Cloud Firestore, bạn nên tối ưu hoá thứ tự của các trường trong chỉ mục. Để thực hiện việc này, bạn phải đảm bảo chỉ mục của mình được sắp xếp theo thứ tự từ trái sang phải để truy vấn chuyển sang một tập dữ liệu nhằm ngăn chặn việc quét các mục nhập chỉ mục không liên quan.

Giả sử bạn muốn tìm kiếm trong một tập hợp các nhân viên để tìm những nhân viên có mức lương lớn hơn 100.000 và số năm kinh nghiệm lớn hơn 0. Dựa trên hiểu biết về tập dữ liệu, bạn biết rằng ràng buộc về tiền lương mang tính lựa chọn hơn so với ràng buộc về kinh nghiệm. Chỉ mục lý tưởng giúp giảm số lần quét chỉ mục là (salary [...], experience [...]). Do đó, một truy vấn nhanh và tiết kiệm chi phí sẽ sắp xếp salary trước experience và có dạng như sau:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

Node.js

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .orderBy("salary")
  .orderBy("experience");

Python

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .order_by("salary")
  .order_by("experience");

Các phương pháp hay nhất để tối ưu hoá chỉ mục

Khi tối ưu hoá các chỉ mục, hãy lưu ý những phương pháp hay nhất sau đây.

Các trường chỉ mục thứ tự theo sau là trường phạm vi hoặc trường bất đẳng thức có chọn lọc nhất

Cloud Firestore sử dụng các trường ở ngoài cùng bên trái của một chỉ mục tổng hợp để đáp ứng các điều kiện ràng buộc bằng nhau và giới hạn phạm vi hoặc bất đẳng thức (nếu có) trên trường đầu tiên của truy vấn orderBy(). Những quy tắc ràng buộc này có thể làm giảm số lượng mục chỉ mục mà Cloud Firestore quét. Cloud Firestore sử dụng các trường còn lại của chỉ mục để đáp ứng các điều kiện ràng buộc khác về phạm vi hoặc bất đẳng thức của truy vấn. Những quy tắc ràng buộc này không làm giảm số lượng mục nhập chỉ mục mà Cloud Firestore quét, nhưng sẽ lọc ra những tài liệu không khớp để giảm số lượng tài liệu được trả về cho ứng dụng.

Để biết thêm thông tin về cách tạo chỉ mục hiệu quả, hãy xem định nghĩa về chỉ mục hoàn hảo.

Các trường thứ tự theo thứ tự giảm dần của tính chọn lọc giới hạn truy vấn

Để đảm bảo Cloud Firestore chọn chỉ mục tối ưu cho truy vấn của bạn, hãy chỉ định mệnh đề orderBy() sắp xếp các trường theo thứ tự giảm dần của độ chọn lọc giới hạn truy vấn. Độ chọn lọc cao hơn sẽ khớp với một nhóm nhỏ tài liệu, trong khi độ chọn lọc thấp hơn sẽ khớp với một nhóm tài liệu lớn hơn. Đảm bảo rằng bạn chọn các trường phạm vi hoặc không bằng nhau có độ chọn lọc cao hơn trong chỉ mục sắp xếp trước hơn các trường có độ chọn lọc thấp hơn.

Để giảm thiểu số lượng tài liệu mà Cloud Firestore quét và trả về qua mạng, bạn phải luôn sắp xếp các trường theo thứ tự giảm dần của độ chọn lọc giới hạn truy vấn. Nếu tập hợp kết quả không theo thứ tự bắt buộc và tập hợp kết quả dự kiến sẽ có kích thước nhỏ, bạn có thể triển khai logic phía máy khách để sắp xếp lại theo thứ tự mong muốn của mình.

Ví dụ: giả sử bạn muốn tìm kiếm trong một tập hợp các nhân viên để tìm những nhân viên có mức lương cao hơn 100.000 nhân viên và sắp xếp kết quả theo năm kinh nghiệm của nhân viên đó. Nếu bạn dự kiến chỉ một số ít nhân viên có mức lương hơn 100.000 nhân viên, thì cách hiệu quả nhất để viết truy vấn như sau:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .orderBy("salary")
  .get()
  .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
          // Order results by `experience`
        }
    });;

Node.js

const querySnapshot = await db.collection('employees')
                              .where("salary", ">", 100000)
                              .orderBy("salary")
                              .get();

// Order results by `experience`

Python

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

Mặc dù việc thêm thứ tự trên experience vào truy vấn sẽ dẫn đến cùng một nhóm tài liệu và tránh việc sắp xếp lại kết quả trên máy khách, truy vấn có thể đọc nhiều mục nhập chỉ mục không liên quan hơn so với truy vấn trước đó. Điều này là do Cloud Firestore luôn ưu tiên một chỉ mục có tiền tố các trường chỉ mục khớp với mệnh đề theo thứ tự của truy vấn. Nếu experience được thêm vào thứ tự theo mệnh đề, thì Cloud Firestore sẽ chọn chỉ mục (experience [...], salary [...]) để tính toán kết quả truy vấn. Vì không có quy tắc ràng buộc nào khác trên experience, nên Cloud Firestore sẽ đọc tất cả các mục nhập chỉ mục của tập hợp employees trước khi áp dụng bộ lọc salary để tìm tập hợp kết quả cuối cùng. Điều này có nghĩa là các mục nhập chỉ mục không đáp ứng bộ lọc salary vẫn được đọc, do đó làm tăng độ trễ và chi phí của truy vấn.

Giá

Các truy vấn có bộ lọc phạm vi và bất đẳng thức trên nhiều trường sẽ được lập hoá đơn dựa trên các mục đã đọc và chỉ mục trong tài liệu.

Để biết thông tin chi tiết, hãy xem trang Định giá.

Hạn chế

Ngoài giới hạn đối với truy vấn, hãy lưu ý các giới hạn sau trước khi sử dụng truy vấn có bộ lọc phạm vi và bộ lọc bất đẳng thức trên nhiều trường:

  • Những truy vấn có bộ lọc phạm vi hoặc bộ lọc không bằng trên các trường tài liệu và chỉ giới hạn bằng đẳng thức trên khoá tài liệu (__name__) không được hỗ trợ.
  • Cloud Firestore giới hạn số lượng trường phạm vi hoặc trường bất đẳng thức ở mức 10. Điều này giúp tránh việc truy vấn trở nên quá tốn kém để chạy.

Bước tiếp theo