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