Firestore Python SDK – count() aggregation

Question:

I’m using Firebase Firestore in my Python project (with their official Python SDK) and having trouble performing count() aggregation. This funciton is supported according to their docs. However, they do not provide Python example ( they do in other parts of documentation ). I tried to play with it in Python console, tried something like this:

query = db.collection('videos').where('status', '==', 'pending')
query.count()

without any luck. So I’m wondering how is it possible to implement? Does Python SDK support this functionality?

Answers:

Update:

count() query is now available in Firebase Admin SDK from version 6.1.0.


Firebase Admin Python SDK doesn’t support that query yet. You can still use the runAggregationQuery REST API meanwhile. The Google Cloud Firestore Python SDK has Aggregation result types available from v2.7.0+ so it should be available in Admin SDK soon.

Answered By: Dharmaraj

Although the API for this purpose is not fully ready but it’s coming along. If you don’t wanna use the REST API as suggested by @Dharmaraj, you can do something like this for now:

from google.cloud.firestore_v1.services.firestore import FirestoreClient
from google.cloud.firestore_v1.types.document import Value
from google.cloud.firestore_v1.types.firestore import RunAggregationQueryRequest
from google.cloud.firestore_v1.types.query import (
    StructuredAggregationQuery,
    StructuredQuery,
)

Aggregation = StructuredAggregationQuery.Aggregation
CollectionSelector = StructuredQuery.CollectionSelector
Count = Aggregation.Count
FieldFilter = StructuredQuery.FieldFilter
FieldReference = StructuredQuery.FieldReference
Filter = StructuredQuery.Filter
Operator = StructuredQuery.FieldFilter.Operator


client = FirestoreClient()
project_id = ""
request = RunAggregationQueryRequest(
    parent=f"projects/{project_id}/databases/(default)/documents",
    structured_aggregation_query=StructuredAggregationQuery(
        structured_query=StructuredQuery(
            from_=[CollectionSelector(collection_id="videos")],
            where=Filter(
                field_filter=FieldFilter(
                    field=FieldReference(
                        field_path="status",
                    ),
                    op=Operator.EQUAL,
                    value=Value(string_value="pending"),
                )
            ),
        ),
        aggregations=[Aggregation(count=Count())],
    ),
)

stream = client.run_aggregation_query(request=request)

print(next(stream).result.aggregate_fields["field_1"].integer_value)

Output:

1

Generally the following would work to count the total number of documents in a collection:

def count_documents(collection_id: str) -> int:
    client = FirestoreClient()
    project_id = ""
    request = RunAggregationQueryRequest(
        parent=f"projects/{project_id}/databases/(default)/documents",
        structured_aggregation_query=StructuredAggregationQuery(
            structured_query=StructuredQuery(
                from_=[CollectionSelector(collection_id=collection_id)]
            ),
            aggregations=[Aggregation(count=Count())],
        ),
    )

    stream = client.run_aggregation_query(request=request)

    return next(stream).result.aggregate_fields["field_1"].integer_value


print(count_documents(collection_id="videos"))

Output:

10

Make sure that you have google-cloud-firestore>=2.7.3 and also remember to set the value of project_id variable in the count_documents function accordingly.

Answered By: Sarmad Gulzar