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)
המשך
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);
שיקולים בהוספה לאינדקס
לפני שמריצים את השאילתות, כדאי לקרוא על [שאילתות][1] ועל Cloud Firestore [מודל הנתונים][2].
ב-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 סורק, אבל הן מסננות מסמכים שלא תואמים כך שמספר המסמכים שמוחזרים ללקוחות קטן יותר.
מידע נוסף על יצירת אינדקסים יעילים זמין במאמר [מאפייני אינדקס][4].
סידור השדות בסדר יורד של סלקטיביות אילוצי השאילתה
כדי לוודא ש-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המסנן עדיין נקראות, ולכן זמן האחזור והעלות של השאילתה גדלים.
תמחור
החיוב על שאילתות עם מסנני טווח ואי-שוויון בכמה שדות מבוסס על מספר המסמכים שנקראו ומספר הרשומות באינדקס שנקראו.
מידע מפורט זמין בדף [תמחור][5].
מגבלות
בנוסף ל[מגבלות על שאילתות][6], חשוב לשים לב למגבלות הבאות לפני שמשתמשים בשאילתות עם מסנני טווח ומסנני אי-שוויון בכמה שדות:
- אין תמיכה בשאילתות עם מסנני טווח או אי-שוויון בשדות של מסמכים, ורק אילוצי שוויון במפתח המסמך
(__name__). - ב-Cloud Firestore מספר השדות של טווח או אי-שוויון מוגבל ל-10. המטרה היא למנוע מצב שבו עלות ההרצה של שאילתות תהיה גבוהה מדי.
המאמרים הבאים
- [מידע נוסף על אופטימיזציה של שאילתות][3]
- מידע נוסף על [ביצוע שאילתות פשוטות ומורכבות][8]
- הסבר על האופן שבו [Cloud Firestore משתמש באינדקסים][9].
[1]: /docs/firestore/query-data/get-data [2]: /docs/firestore/data-model [3]: /docs/firestore/query-data/multiple-range-optimize-indexes [4]: /docs/firestore/concepts/index-overview#index_properties [5]: /docs/firestore/pricing [6]: /docs/firestore/query-data/queries#query_limitations [7]: https://en.wikipedia.org/wiki/Disjunctive_normal_form [8]: /docs/firestore/query-data/queries [9]: /docs/firestore/concepts/index-overview [10]: /docs/firestore/query-data/multiple-range-optimize-indexes