ב-Cloud Firestore יש תמיכה בשימוש במסנני טווחים ובמסנני אי-שוויון במספר שדות בשאילתה אחת. אפשר להשתמש בתנאי טווח ובתנאי אי-שוויון בכמה שדות, ולפשט את פיתוח האפליקציה על ידי הענקת גישה ל-Cloud Firestore להטמעת הלוגיקה שלאחר הסינון.
מסננים של טווח ואי-שוויון בשדות מרובים
השאילתה הבאה משתמשת במסנני טווח של אוכלוסייה וצפיפות כדי להחזיר את כל הערים שבהן האוכלוסייה גדולה מ-1,000,000 אנשים, וצפיפות האוכלוסייה קטנה מ-10,000 אנשים ליחידת שטח.
גרסת אינטרנט 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];
Java ב-Android
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin+KTX Android
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Go
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);
שיקולים לגבי הוספה לאינדקס
לפני שמריצים את השאילתות, כדאי לקרוא על שאילתות ועל מודל הנתונים של Cloud Firestore.
ב-Cloud Firestore, הסעיף ORDER BY
של השאילתה קובע באילו אינדקסים אפשר להשתמש כדי להציג את השאילתה. לדוגמה, לשאילתה ORDER BY a ASC, b ASC
נדרש אינדקס מורכב בשדות a ASC, b ASC
.
כדי לשפר את הביצועים והעלות של שאילתות Cloud Firestore, צריך לבצע אופטימיזציה של סדר השדות באינדקס. כדי לעשות זאת, צריך לוודא שהאינדקס מסודר משמאל לימין, כך שהשאילתה תתמצת למערך נתונים שימנע סריקת רשומות אינדקס מיותרות.
נניח שאתם רוצים לחפש באוסף של עובדים ולמצוא עובדים בארצות הברית שהמשכורת שלהם גבוהה מ-100,000$ ומספר שנות הניסיון שלהם גדול מאפס. על סמך ההבנה שלכם של מערך הנתונים, אתם יודעים שהאילוץ על השכר סלקטיבי יותר מהאילוץ על ניסיון העבודה. האינדקס האידיאלי שיצמצם את מספר סריקות האינדקס הוא (salary [...], experience [...])
. לכן, השאילתה שתהיה מהירה ומשתלמת תסדר את salary
לפני experience
ותיראה כך:
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");
שיטות מומלצות לאופטימיזציה של מדדים
כשמבצעים אופטימיזציה של אינדקסים, כדאי לזכור את השיטות המומלצות הבאות.
סדר שדות האינדקס לפי שוויות, ואחריהם השדה עם הטווח או אי-השוויון הסלקטיבי ביותר
Cloud Firestore משתמש בשדות הכי שמאליים של אינדקס מורכב כדי לעמוד במגבלות השוויון ובאילוץ הטווח או אי השוויון, אם יש, בשדה הראשון של השאילתה orderBy()
. האילוצים האלה יכולים לצמצם את מספר רשומות האינדקס ש-Cloud Firestore סורק. Cloud Firestore משתמש בשדות הנותרים באינדקס כדי לעמוד במגבלות אחרות של טווח או אי-שוויון של השאילתה. האילוצים האלה לא מפחיתים את מספר הרשומות באינדקס ש-Cloud Firestore סורק, אבל הם מסננים מסמכים שלא תואמים, כך שמספר המסמכים שמוחזרים ללקוחות מצטמצם.
מידע נוסף על יצירת אינדקסים יעילים זמין במאמר מאפייני אינדקס.
סידור שדות בסדר יורד של סלקטיביות של אילוצי שאילתות
כדי לוודא ש-Cloud Firestore יבחר את האינדקס האופטימלי לשאילתה, צריך לציין תנאי orderBy()
שמסדר את השדות בסדר יורד של סלקטיביות האילוצים של השאילתה. ככל שהסלקטיביות גבוהה יותר, כך מתבצעות התאמות לקבוצת משנה קטנה יותר של מסמכים, וככל שהסלקטיביות נמוכה יותר, כך מתבצעות התאמות לקבוצת משנה גדולה יותר של מסמכים. חשוב לבחור שדות טווח או אי-שוויון עם סלקטיביות גבוהה יותר בשלב מוקדם יותר ברשימת האינדקסים מאשר שדות עם סלקטיביות נמוכה יותר.
כדי לצמצם את מספר המסמכים ש-Cloud Firestore סורק ומחזיר ברשת, צריך תמיד לסדר את השדות בסדר יורד של סלקטיביות של מגבלות השאילתה. אם התוצאה לא מופיעה בסדר הנדרש והתוצאה צפויה להיות קטנה, אפשר להטמיע לוגיקה בצד הלקוח כדי לשנות את הסדר לפי הציפיות שלכם.
לדוגמה, נניח שאתם רוצים לחפש באוסף עובדים כדי למצוא עובדים שהשכר שלהם גבוה מ-100,000$, ולסדר את התוצאות לפי שנת הניסיון של העובד. אם אתם מצפים שרק למספר קטן של עובדים יהיו משכורות גבוהות מ-100,000$, הדרך היעילה ביותר לכתוב את השאילתה היא:
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`
הוספת סדר של experience
לשאילתה תניב את אותה קבוצה של מסמכים ותבטל את הצורך בסדר מחדש של התוצאות בלקוחות, אבל השאילתה עשויה לקרוא הרבה יותר רשומות מיותרות באינדקס בהשוואה לשאילתה הקודמת. הסיבה לכך היא ש-Cloud Firestore תמיד מעדיף אינדקס שהתחילית של שדות האינדקס שלו תואמת לתנאי order by בשאילתה. אם מוסיפים את experience
להזמנה לפי סעיף, Cloud Firestore יבחר את האינדקס (experience [...], salary [...])
לחישוב תוצאות של שאילתות. מכיוון שאין אילוצים אחרים על experience
, Cloud Firestore יקרא את כל רשומות האינדקס של האוסף employees
לפני החלת המסנן salary
כדי למצוא את התוצאה הסופית. המשמעות היא שעדיין מתבצעת קריאה של רשומות אינדקס שלא עומדות בקריטריונים של המסנן salary
, וכך משך האחזור והעלות של השאילתה עולים.
תמחור
שאילתות עם מסנני טווח ואי-שוויון בכמה שדות יחויבו על סמך מסמכים שנקראו ורשומות שנוספו לאינדקס שנקראו.
מידע מפורט זמין בדף Pricing.
מגבלות
מלבד מגבלות השאילתות, שימו לב למגבלות הבאות לפני שמשתמשים בשאילתות עם מסננים של טווח ואי-שוויון בשדות מרובים:
- אין תמיכה בשאילתות עם מסנני טווח או אי-שוויון בשדות המסמך, ורק באילוצים של שוויון במפתח המסמך
(__name__)
. - הפונקציה Cloud Firestore מגבילה את מספר שדות הטווח או אי השוויון ל-10. המטרה היא למנוע הוצאות יקרות מדי על הרצת שאילתות.
המאמרים הבאים
- מידע נוסף בנושא אופטימיזציה של שאילתות.
- מידע נוסף על ביצוע שאילתות פשוטות ומורכבות
- הסבר על האופן שבו Cloud Firestore משתמש באינדקסים