שאילתת צבירה מעבדת את הנתונים מכניסות אינדקס מרובות כדי להחזיר ערך סיכום יחיד.
Cloud Firestore תומך בשאילתות הצבירה הבאות:
-
count()
-
sum()
-
average()
Cloud Firestore מחשבת את הצבירה ומשדרת רק את התוצאה חזרה לאפליקציה שלך. בהשוואה לביצוע שאילתה מלאה וחישוב הצבירה באפליקציה שלך, שאילתות צבירה חוסכות הן בקריאה של מסמכים מחויבים והן בתים שהועברו.
שאילתות צבירה מסתמכות על תצורת האינדקס הקיימת שבה השאילתות שלך כבר משתמשות, ומתארכות באופן יחסי למספר ערכי האינדקס שנסרקו. האחזור גדל עם מספר הפריטים בצבירה.
השתמש בצבירה count()
שאילתת הצבירה count()
מאפשרת לך לקבוע את מספר המסמכים באוסף או שאילתה.
עיין בנתונים לדוגמה שהגדרנו בקבלת נתונים .
צבירת ה- count()
הבאה מחזירה את המספר הכולל של הערים באוסף cities
.
Web modular API
const coll = collection(db, "cities"); const snapshot = await getCountFromServer(coll); console.log('count: ', snapshot.data().count);
מָהִיר
let query = db.collection("cities") let countQuery = query.count do { let snapshot = try await countQuery.getAggregation(source: .server) print(snapshot.count) } catch { print(error) }
Objective-C
FIRCollectionReference *query = [self.db collectionWithPath:@"cities"]; [query.count aggregationWithSource:FIRAggregateSourceServer completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error fetching count: %@", error); } else { NSLog(@"Cities count: %@", snapshot.count); } }];
Java
Query query = db.collection("cities"); AggregateQuery countQuery = query.count(); countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() { @Override public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) { if (task.isSuccessful()) { // Count fetched successfully AggregateQuerySnapshot snapshot = task.getResult(); Log.d(TAG, "Count: " + snapshot.getCount()); } else { Log.d(TAG, "Count failed: ", task.getException()); } } });
Kotlin+KTX
val query = db.collection("cities") val countQuery = query.count() countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task -> if (task.isSuccessful) { // Count fetched successfully val snapshot = task.result Log.d(TAG, "Count: ${snapshot.count}") } else { Log.d(TAG, "Count failed: ", task.getException()) } }
Dart
// Returns number of documents in users collection db.collection("users").count().get().then( (res) => print(res.count), onError: (e) => print("Error completing: $e"), );
ללכת
Java
CollectionReference collection = db.collection("cities"); AggregateQuerySnapshot snapshot = collection.count().get().get(); System.out.println("Count: " + snapshot.getCount());
Node.js
const collectionRef = db.collection('cities'); const snapshot = await collectionRef.count().get(); console.log(snapshot.data().count);
פִּיתוֹן
צבירה count()
לוקחת בחשבון מסננים כלשהם בשאילתה וכל סעיפי limit
.
Web modular API
const coll = collection(db, "cities"); const q = query(coll, where("state", "==", "CA")); const snapshot = await getCountFromServer(q); console.log('count: ', snapshot.data().count);
מָהִיר
let query = db.collection("cities").whereField("state", isEqualTo: "CA") let countQuery = query.count do { let snapshot = try await countQuery.getAggregation(source: .server) print(snapshot.count) } catch { print(error) }
Objective-C
FIRQuery *query = [[self.db collectionWithPath:@"cities"] queryWhereField:@"state" isEqualTo:@"CA"]; [query.count aggregationWithSource:FIRAggregateSourceServer completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error fetching count: %@", error); } else { NSLog(@"Cities count: %@", snapshot.count); } }];
Java
Query query = db.collection("cities").whereEqualTo("state", "CA"); AggregateQuery countQuery = query.count(); countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() { @Override public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) { if (task.isSuccessful()) { // Count fetched successfully AggregateQuerySnapshot snapshot = task.getResult(); Log.d(TAG, "Count: " + snapshot.getCount()); } else { Log.d(TAG, "Count failed: ", task.getException()); } } });
Kotlin+KTX
val query = db.collection("cities").whereEqualTo("state", "CA") val countQuery = query.count() countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task -> if (task.isSuccessful) { // Count fetched successfully val snapshot = task.result Log.d(TAG, "Count: ${snapshot.count}") } else { Log.d(TAG, "Count failed: ", task.getException()) } }
Dart
// This also works with collectionGroup queries. db.collection("users").where("age", isGreaterThan: 10).count().get().then( (res) => print(res.count), onError: (e) => print("Error completing: $e"), );
ללכת
Java
CollectionReference collection = db.collection("cities"); Query query = collection.whereEqualTo("state", "CA"); AggregateQuerySnapshot snapshot = query.count().get().get(); System.out.println("Count: " + snapshot.getCount());
Node.js
const collectionRef = db.collection('cities'); const query = collectionRef.where('state', '==', 'CA'); const snapshot = await query.count().get(); console.log(snapshot.data().count);
פִּיתוֹן
השתמש בצבירה sum()
השתמש בצבירה sum()
כדי להחזיר את הסכום הכולל של ערכים מספריים התואמים לשאילתה נתונה - לדוגמה:
Web modular API
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { totalPopulation: sum('population') }); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Java
collection = db.collection("cities"); snapshot = collection.aggregate(sum("population")).get().get(); System.out.println("Sum: " + snapshot.get(sum("population")));
Node.js
const coll = firestore.collection('cities'); const sumAggregateQuery = coll.aggregate({ totalPopulation: AggregateField.sum('population'), }); const snapshot = await sumAggregateQuery.get(); console.log('totalPopulation: ', snapshot.data().totalPopulation);
צבירת sum()
לוקחת בחשבון מסננים כלשהם בשאילתה וכל סעיפי מגבלה - לדוגמה:
Web modular API
const coll = collection(firestore, 'cities'); const q = query(coll, where('capital', '==', true)); const snapshot = await getAggregateFromServer(q, { totalPopulation: sum('population') }); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); snapshot = query.aggregate(sum("population")).get().get(); System.out.println("Sum: " + snapshot.get(sum("population")));
Node.js
const coll = firestore.collection('cities'); const q = coll.where("capital", "==", true); const sumAggregateQuery = q.aggregate({ totalPopulation: AggregateField.sum('population'), }); const snapshot = await sumAggregateQuery.get(); console.log('totalPopulation: ', snapshot.data().totalPopulation);
השתמש average()
השתמש בצבירה average()
כדי להחזיר את הממוצע של ערכים מספריים התואמים שאילתה נתונה - לדוגמה:
Web modular API
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { averagePopulation: average('population') }); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); snapshot = collection.aggregate(average("population")).get().get(); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const averageAggregateQuery = coll.aggregate({ averagePopulation: AggregateField.average('population'), }); const snapshot = await averageAggregateQuery.get(); console.log('averagePopulation: ', snapshot.data().averagePopulation);
צבירת average()
לוקחת בחשבון מסננים כלשהם בשאילתה וכל סעיפי מגבלה - לדוגמה:
Web modular API
const coll = collection(firestore, 'cities'); const q = query(coll, where('capital', '==', true)); const snapshot = await getAggregateFromServer(q, { averagePopulation: average('population') }); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); snapshot = query.aggregate(average("population")).get().get(); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const q = coll.where("capital", "==", true); const averageAggregateQuery = q.aggregate({ averagePopulation: AggregateField.average('population'), }); const snapshot = await averageAggregateQuery.get(); console.log('averagePopulation: ', snapshot.data().averagePopulation);
חשב צבירות מרובות בשאילתה
ניתן לשלב מספר צבירות בצנרת צבירה אחת. זה יכול להפחית את מספר קריאות האינדקס הנדרשות. אם השאילתה כוללת צבירות על שדות מרובים, ייתכן שהשאילתה דורשת אינדקס מורכב. במקרה כזה, Cloud Firestore מציעה אינדקס.
הדוגמה הבאה מבצעת צבירות מרובות בשאילתת צבירה אחת:
Web modular API
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { countOfDocs: count(), totalPopulation: sum('population'), averagePopulation: average('population') }); console.log('countOfDocs: ', snapshot.data().countOfDocs); console.log('totalPopulation: ', snapshot.data().totalPopulation); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); AggregateQuery aggregateQuery = query.aggregate(count(), sum("population"), average("population")); snapshot = aggregateQuery.get().get(); System.out.println("Count: " + snapshot.getCount()); System.out.println("Sum: " + snapshot.get(sum("population"))); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const aggregateQuery = coll.aggregate({ countOfDocs: AggregateField.count(), totalPopulation: AggregateField.sum('population'), averagePopulation: AggregateField.average('population') }); const snapshot = await aggregateQuery.get(); console.log('countOfDocs: ', snapshot.data().countOfDocs); console.log('totalPopulation: ', snapshot.data().totalPopulation); console.log('averagePopulation: ', snapshot.data().averagePopulation);
שאילתות עם מספר צבירה כוללות רק את המסמכים המכילים את כל השדות בכל צבירה. זה עשוי להוביל לתוצאות שונות מביצוע כל צבירה בנפרד.
כללי אבטחה עבור שאילתות צבירה
כללי האבטחה של Cloud Firestore פועלים באופן זהה על שאילתות צבירה כמו על שאילתות המחזירות מסמכים. במילים אחרות, אם ורק אם הכללים שלך מאפשרים ללקוחות לבצע שאילתות מסוימות של איסוף או קבוצת איסוף, לקוחות יכולים גם לבצע את הצבירה בשאילתות אלו. למידע נוסף על האופן שבו כללי האבטחה של Cloud Firestore מתקשרים עם שאילתות .
התנהגות ומגבלות
כשאתה עובד עם שאילתות צבירה, שים לב להתנהגות ולמגבלות הבאות:
אינך יכול להשתמש בשאילתות צבירה עם מאזינים בזמן אמת ושאילתות לא מקוונות. שאילתות צבירה נתמכות רק באמצעות תגובת שרת ישירה. שאילתות מוגשות רק על ידי ה-Cloud Firestore, תוך דילוג על המטמון המקומי וכל העדכונים המאוחסנים. התנהגות זו זהה לפעולות המבוצעות בתוך עסקאות Cloud Firestore .
אם צבירה לא יכולה להיפתר תוך 60 שניות, היא מחזירה שגיאה
DEADLINE_EXCEEDED
. הביצועים תלויים בתצורת האינדקס שלך ובגודל מערך הנתונים.אם לא ניתן להשלים את הפעולה בתוך המועד האחרון של 60 שניות, פתרון אפשרי הוא להשתמש במונים עבור מערכי נתונים גדולים.
שאילתות צבירה נקראות מערכי אינדקס וכוללות רק שדות שנוספו לאינדקס.
הוספת סעיף
OrderBy
לשאילתת צבירה מגבילה את הצבירה למסמכים שבהם קיים שדה המיון.עבור צבירות
sum()
ו-average()
, מתעלמים מערכים לא מספריים. צבירותsum()
ו-average()
לוקחות בחשבון רק ערכי מספרים שלמים וערכי מספר נקודה צפה.בעת שילוב של צבירות מרובות בשאילתה אחת, שים לב ש
sum()
ו-average()
מתעלמים מערכים לא מספריים בעודcount()
כולל ערכים לא מספריים.אם תשלב צבירות שנמצאות על שדות שונים, החישוב כולל רק את המסמכים המכילים את כל השדות הללו.
תמחור
התמחור עבור שאילתות צבירה תלוי במספר כניסות האינדקס המותאמות לשאילתה. אתה מחויב במספר קטן של קריאות עבור מספר רב של ערכים תואמים.
ראה מידע תמחור מפורט יותר.