ב-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$, ולסדר את התוצאות לפי שנות הניסיון של העובד. אם אתם צופים שרק למספר קטן של עובדים יהיו משכורות של יותר מ-400,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
לתנאי order by, הפונקציה Cloud Firestore תבחר את האינדקס (experience [...], salary [...])
לצורך חישוב תוצאות השאילתה. מאחר שאין אילוצים אחרים על experience
, הפונקציה Cloud Firestore תקריא את כל הרשומות באינדקס של האוסף employees
לפני החלת המסנן salary
כדי למצוא את קבוצת התוצאות הסופית. המשמעות היא שעדיין מתבצעת קריאה של רשומות אינדקס שלא עומדות בקריטריונים של המסנן salary
, וכך משך האחזור והעלות של השאילתה עולים.
תמחור
חיפושים עם מסנני טווח ואי-שוויון בכמה שדות מחויבים על סמך מספר המסמכים שנקראו ומספר הרשומות שנוספו לאינדקס.
מידע מפורט זמין בדף Pricing.
מגבלות
בנוסף למגבלות על שאילתות, חשוב לשים לב למגבלות הבאות לפני שמשתמשים בשאילתות עם מסנני טווחים ויחסי אי-שוויון במספר שדות:
- אין תמיכה בשאילתות עם מסנני טווח או אי-שוויון בשדות המסמך, ורק באילוצים של שוויון במפתח המסמך
(__name__)
. - Cloud Firestore מגביל את מספר השדות של טווחים או אי-שוויונות ל-10. המטרה היא למנוע הוצאות יקרות מדי על הרצת שאילתות.
המאמרים הבאים
- מידע נוסף על אופטימיזציה של שאילתות
- מידע נוסף על ביצוע שאילתות פשוטות ומשולבות
- הסבר על האופן שבו Cloud Firestore משתמש באינדקסים