عد المستندات مع استعلامات التجميع

يقوم استعلام التجميع بمعالجة البيانات من إدخالات الفهرس المتعددة لإرجاع قيمة ملخص واحدة.

يدعم Cloud Firestore استعلام التجميع count() . count() يسمح لك بتحديد عدد المستندات في مجموعة أو استعلام. يقوم الخادم بحساب العدد، ويرسل النتيجة فقط، وهي عدد صحيح واحد، مرة أخرى إلى التطبيق الخاص بك، مما يوفر عمليات قراءة المستند المفوترة والبايتات المنقولة، مقارنة بتنفيذ الاستعلام الكامل.

تعتمد استعلامات التجميع على تكوين الفهرس الحالي الذي تستخدمه استعلاماتك بالفعل، ويتم قياسه بشكل متناسب مع عدد إدخالات الفهرس التي تم فحصها. وهذا يعني أن مجموعات البيانات الصغيرة إلى المتوسطة الحجم تؤدي أداءها في غضون 20 إلى 40 مللي ثانية، على الرغم من أن زمن الوصول يزداد مع عدد العناصر التي يتم حسابها.

استخدم تجميع count()

ارجع إلى البيانات النموذجية التي قمنا بإعدادها في الحصول على البيانات .

يُرجع تجميع count() التالي إجمالي عدد المدن في مجموعة cities .

Web modular API

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
سويفت
ملاحظة: هذا المنتج غير متوفر في أنظمة watchOS وApp Clip.
let query = db.collection("cities")
let countQuery = query.count
do {
    let snapshot = try await countQuery.getAggregation(source: .server)
    print(snapshot.count)
} catch {
    print(error)
}
ج موضوعية
ملاحظة: هذا المنتج غير متوفر في أنظمة watchOS وApp Clip.
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"),
    );
يذهب
package firestore

import (
	"context"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
	firestorepb "cloud.google.com/go/firestore/apiv1/firestorepb"
)

func createCountQuery(w io.Writer, projectID string) error {

	// Instantiate the client
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return err
	}
	defer client.Close()

	collection := client.Collection("users")
	query := collection.Where("born", ">", 1850)

	// `alias` argument--"all"--provides a key for accessing the aggregate query
	// results. The alias value must be unique across all aggregation aliases in
	// an aggregation query and must conform to allowed Document field names.
	//
	// See https://cloud.google.com/firestore/docs/reference/rpc/google.firestore.v1#document for details.
	aggregationQuery := query.NewAggregationQuery().WithCount("all")
	results, err := aggregationQuery.Get(ctx)
	if err != nil {
		return err
	}

	count, ok := results["all"]
	if !ok {
		return errors.New("firestore: couldn't get alias for COUNT from results")
	}

	countValue := count.(*firestorepb.Value)
	fmt.Fprintf(w, "Number of results from query: %d\n", countValue.GetIntegerValue())
	return nil
}
جافا
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);
      
بايثون
from google.cloud import firestore
from google.cloud.firestore_v1 import aggregation
from google.cloud.firestore_v1.base_query import FieldFilter


def create_count_query(project_id: str) -> None:
    """Builds an aggregate query that returns the number of results in the query.

    Arguments:
      project_id: your Google Cloud Project ID
    """
    client = firestore.Client(project=project_id)

    collection_ref = client.collection("users")
    query = collection_ref.where(filter=FieldFilter("born", ">", 1800))
    aggregate_query = aggregation.AggregationQuery(query)

    # `alias` to provides a key for accessing the aggregate query results
    aggregate_query.count(alias="all")

    results = aggregate_query.get()
    for result in results:
        print(f"Alias of results from query: {result[0].alias}")
        print(f"Number of results from query: {result[0].value}")

يأخذ تجميع 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);
سويفت
ملاحظة: هذا المنتج غير متوفر في أنظمة watchOS وApp Clip.
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)
}
ج موضوعية
ملاحظة: هذا المنتج غير متوفر في أنظمة watchOS وApp Clip.
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"),
    );
يذهب
package firestore

import (
	"context"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
	firestorepb "cloud.google.com/go/firestore/apiv1/firestorepb"
)

func createCountQuery(w io.Writer, projectID string) error {

	// Instantiate the client
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return err
	}
	defer client.Close()

	collection := client.Collection("users")
	query := collection.Where("born", ">", 1850)

	// `alias` argument--"all"--provides a key for accessing the aggregate query
	// results. The alias value must be unique across all aggregation aliases in
	// an aggregation query and must conform to allowed Document field names.
	//
	// See https://cloud.google.com/firestore/docs/reference/rpc/google.firestore.v1#document for details.
	aggregationQuery := query.NewAggregationQuery().WithCount("all")
	results, err := aggregationQuery.Get(ctx)
	if err != nil {
		return err
	}

	count, ok := results["all"]
	if !ok {
		return errors.New("firestore: couldn't get alias for COUNT from results")
	}

	countValue := count.(*firestorepb.Value)
	fmt.Fprintf(w, "Number of results from query: %d\n", countValue.GetIntegerValue())
	return nil
}
جافا
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);
      
بايثون
from google.cloud import firestore
from google.cloud.firestore_v1 import aggregation
from google.cloud.firestore_v1.base_query import FieldFilter


def create_count_query(project_id: str) -> None:
    """Builds an aggregate query that returns the number of results in the query.

    Arguments:
      project_id: your Google Cloud Project ID
    """
    client = firestore.Client(project=project_id)

    collection_ref = client.collection("users")
    query = collection_ref.where(filter=FieldFilter("born", ">", 1800))
    aggregate_query = aggregation.AggregationQuery(query)

    # `alias` to provides a key for accessing the aggregate query results
    aggregate_query.count(alias="all")

    results = aggregate_query.get()
    for result in results:
        print(f"Alias of results from query: {result[0].alias}")
        print(f"Number of results from query: {result[0].value}")

تعمل قواعد أمان Cloud Firestore بنفس الطريقة في استعلامات التجميع count() كما في الاستعلامات العادية التي تُرجع المستندات. بمعنى آخر، إذا كانت القواعد الخاصة بك تسمح للعملاء بتنفيذ مجموعة معينة أو استعلامات مجموعة المجموعة فقط، فيمكن للعملاء أيضًا إجراء تجميع count() على تلك الاستعلامات. تعرف على المزيد حول كيفية تفاعل قواعد أمان Cloud Firestore مع الاستعلامات .

محددات

لاحظ القيود التالية على استعلام التجميع count() :

  • استعلامات التجميع count() مدعومة حاليًا فقط من خلال استجابة الخادم المباشرة. يتم تقديم الاستعلامات فقط من خلال الواجهة الخلفية لـ Cloud Firestore، مع تخطي ذاكرة التخزين المؤقت المحلية وأي تحديثات مخزنة مؤقتًا. يتطابق هذا السلوك مع العمليات التي يتم إجراؤها داخل معاملات Cloud Firestore . لا يمكنك حاليًا استخدام استعلامات count() مع المستمعين في الوقت الفعلي والاستعلامات غير المتصلة بالإنترنت.

  • إذا تعذر حل تجميع count() خلال 60 ثانية، فإنه يُرجع خطأ DEADLINE_EXCEEDED . يعتمد الأداء على تكوين الفهرس الخاص بك وعلى حجم مجموعة البيانات.

    إذا تعذر إكمال العملية خلال الموعد النهائي البالغ 60 ثانية، فإن الحل البديل المحتمل هو استخدام العدادات لمجموعات البيانات الكبيرة.

  • يقرأ تجميع count() ‎ من إدخالات الفهرس ويحسب الحقول المفهرسة فقط.

  • تؤدي إضافة جملة OrderBy إلى الاستعلام إلى تقييد عدد المستندات التي يوجد بها حقل الفرز.

التسعير

يعتمد تسعير count() على عدد إدخالات الفهرس المطابقة للاستعلام. يتم محاسبتك على عدد صغير من القراءات لعدد كبير من الإدخالات المطابقة.

انظر المزيد من معلومات التسعير التفصيلية.