Cloud Firestore hỗ trợ sử dụng bộ lọc phạm vi và bất đẳng thức trên nhiều trường trong một truy vấn. Bạn có thể đặt các điều kiện về phạm vi và bất đẳng thức trên nhiều trường và đơn giản hoá 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 sử dụng các bộ lọc phạm vi về dân số và mật độ để trả về tất cả các thành phố có dân số cao hơn 1.000.000 người và mật độ dân số trên 10.000 người/đơn vị diện tích.
Mô-đun phiên bản web 9
const q = query(
collection(db, "cities"),
where('population', '>', 1000000),
where('density', '<', 10000),
);
Swift
let query = db.collection("cities")
.whereField("population", isGreaterThan: 1000000)
.whereField("density", isLessThan: 10000)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
queryWhereField:@"density" isLessThan:@10000];
Android Java
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin+KTX cho Android
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Tiến hành
query := client.Collection("cities").
Where("population", ">", 1000000).
Where("density", "<", 10000)
Java
db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Node.js
db.collection("cities")
.where('population', '>', 1000000),
.where('density', '<', 10000)
Python
from google.cloud import firestore
db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)
PHP
C#
Ruby
query = cities_ref.where("population", ">", "1000000")
.where("density", "<", 10000)
C++
CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
.WhereLessThan("density", FieldValue::Integer(10000));
Unity
CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
.WhereLessThan("density", 10000);
Dart
final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
.where("density", isLessThan: 10000);
Những điều cần cân nhắc khi lập chỉ mục
Trước khi bạn chạy truy vấn của mình, hãy đọc về truy vấn và mô hình dữ liệu Cloud Firestore.
Trong Cloud Firestore, mệnh đề ORDER BY
của truy vấn xác định chỉ mục nào
có thể được sử 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 Cloud Firestore truy vấn, tối ưu hoá thứ tự các trường trong chỉ mục. Để thực hiện việc này, hãy đảm bảo rằng chỉ mục của bạn được sắp xếp theo thứ tự từ trái sang phải để truy vấn chuyển sang tập dữ liệu ngăn chặn việc quét các mục nhập chỉ mục không cần thiết.
Giả sử bạn muốn tìm kiếm trong một nhóm nhân viên và tìm Hoa Kỳ
nhân viên có mức lương trên 100.000 đô la và số năm kinh nghiệm là
lớn hơn 0. Dựa trên hiểu biết của mình 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. Lý tưởng
chỉ mục giúp giảm số lần quét chỉ mục sẽ là
(salary [...], experience [...])
. Do đó, một truy vấn nhanh và
tiết kiệm chi phí sẽ đặt hàng 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ự bằng các trường bằng nhau, 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 chỉ mục tổng hợp để đáp ứng
giới hạn bằng đẳng thức và ràng buộc 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 ràng buộc này có thể làm giảm số lượng chỉ mục
các mục nhập 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 những ràng buộc khác về phạm vi hoặc bất đẳng thức của truy vấn. Các
các điều kiện ràng buộc không làm giảm số lượng mục nhập chỉ mục mà Cloud Firestore quét
nhưng lọc ra những tài liệu không khớp để số lượng tài liệu
trả về cho khách hàng đều bị giảm.
Để biết thêm thông tin về cách tạo chỉ mục hiệu quả, hãy xem phần thuộc tính chỉ mục.
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 rằng Cloud Firestore chọn chỉ mục tối ưu cho truy vấn của bạn,
chỉ định mệnh đề orderBy()
sắp xếp các trường theo thứ tự giảm dần của truy vấn
hạn chế chọn lọc. Độ chọn lọc cao hơn phù hợp với một tập con nhỏ hơn
tài liệu, trong khi độ chọn lọc thấp hơn phù hợp với một nhóm nhỏ 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 bất bình đẳng có độ chọn lọc cao hơn trước đó trong chỉ mục
thứ tự khác với 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ả lại 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 truy vấn hạn chế chọn lọc. Nếu tập hợp kết quả không theo thứ tự yêu cầu và tập hợp kết quả dự kiến sẽ nhỏ, bạn có thể triển khai logic phía máy khách để đặt lại đơn hàng theo mong muốn của bạn khi đặt hàng.
Ví dụ: giả sử bạn muốn tìm kiếm qua một nhóm các nhân viên để tìm Nhân viên tại Hoa Kỳ có mức lương trên 100.000 USD và sắp xếp kết quả tính 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 lớn hơn 100.000 đô la 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ẽ mang lại cùng một nhóm
tài liệu và loại bỏ việc sắp xếp lại thứ tự các kết quả trên máy khách, thì truy vấn có thể
đọc nhiều mục nhập chỉ mục không liên quan hơn 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
thứ tự theo mệnh đề 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ó hạn chế nào khác đối với
experience
, Cloud Firestore sẽ đọc tất cả các mục nhập trong chỉ mục của
Bộ sưu tập employees
trước khi áp dụng bộ lọc salary
để tìm kết quả cuối cùng
bộ kết quả. Điều này có nghĩa là các mục nhập chỉ mục không đáp ứng 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 tài liệu đã đọc và lập chỉ mục các mục đã đọc.
Để biết thông tin chi tiết, hãy xem trang Định giá.
Các điểm 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 các truy vấn có bộ lọc phạm vi và bất đẳng thức trên nhiều trường:
- Các truy vấn có bộ lọc phạm vi hoặc bất đẳng thức trên các trường tài liệu và chỉ có giá trị bằng nhau
các quy tắc ràng buộ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
- Tìm hiểu về cách tối ưu hoá cụm từ tìm kiếm.
- Tìm hiểu thêm về cách thực hiện các truy vấn đơn giản và truy vấn phức hợp.
- Tìm hiểu cách Cloud Firestore sử dụng chỉ mục.