يقوم استعلام التجميع بمعالجة البيانات من إدخالات الفهرس المتعددة لإرجاع قيمة ملخص واحدة.
يدعم 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) }
ج موضوعية
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"), );
يذهب
جافا
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) }
ج موضوعية
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"), );
يذهب
جافا
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);
جافا
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);
جافا
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);
جافا
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);
جافا
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);
جافا
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()
قيمًا غير رقمية.إذا قمت بدمج المجموعات الموجودة في حقول مختلفة، فإن الحساب يتضمن فقط المستندات التي تحتوي على كافة هذه الحقول.
التسعير
يعتمد تسعير استعلامات التجميعات على عدد إدخالات الفهرس المطابقة للاستعلام. يتم محاسبتك على عدد صغير من القراءات لعدد كبير من الإدخالات المطابقة.
انظر المزيد من معلومات التسعير التفصيلية.