The find() Async Generator
find() is the primary method for querying a collection. It returns an async generator that yields model instances one at a time as Firestore streams them.
Signature
| Parameter | Type | Description |
|---|---|---|
filters | list | A list of filter tuples, each produced by a FirestoreField comparison expression. |
parent | BaseFirestoreModel | Parent document instance for subcollection queries. |
projection | Type[BaseModel] | A plain Pydantic model that defines the fields to fetch. See Projections. |
order_by | FieldType or tuple or list | Field or (field, direction) tuple to sort results by. |
limit | int | Maximum number of documents to return. |
offset | int | Number of documents to skip before returning results. |
Filter Syntax
Filters are created by applying comparison operators directly to your model’s class-level field descriptors. Each expression returns a(field_name, operator, value) tuple that find() passes to Firestore.
Comparison Operators
All Available Operators (FirestoreOperators)
| Enum Member | Firestore Operator | Meaning |
|---|---|---|
EQ | == | Equal |
NE | != | Not equal |
LT | < | Less than |
LTE | <= | Less than or equal |
GT | > | Greater than |
GTE | >= | Greater than or equal |
IN | in | Value is in a list |
NOT_IN | not-in | Value is not in a list |
ARRAY_CONTAINS | array_contains | Array field contains value |
ARRAY_CONTAINS_ANY | array_contains_any | Array field contains any of values |
in_() — Match Any Value in a List
Use the .in_() helper method on a FirestoreField to generate an IN filter:
.not_in_() generates a NOT_IN filter:
array_contains() — Filter by Array Membership
Use .array_contains() to find documents where an array field includes a specific value:
.array_contains_any() to match any of multiple values:
Multiple Filters
Pass a list of filter expressions tofilters= to apply all of them. Firestore evaluates them as a logical AND:
find_one() — First Match or None
find_one() runs the same query as find() with limit=1 and returns the first matching instance, or None if nothing matches. It accepts the same filters, parent, projection, and order_by parameters.
get() — Fetch a Document by ID
When you already know a document’s ID, use get() instead of find(). It returns the model instance or None if the document does not exist.
exists() — Check Document Existence
exists() returns True or False without fetching the document’s data. This is more efficient than get() when you only need to verify the document exists.
count() — Count Matching Documents
count() returns an integer representing the number of documents that match the given filters. It uses Firestore’s native count() aggregation when available, falling back to a lightweight select([]) fetch otherwise.
Ordering Results
Control the sort order offind() results with the order_by parameter.
Single Field
Pass a(field, direction) tuple using OrderByDirection.ASCENDING or OrderByDirection.DESCENDING:
Multiple Fields
Pass a list of(field, direction) tuples to sort by multiple fields. Firestore requires a composite index when combining multiple order_by fields with inequality filters:
Pagination with limit and offset
Use limit to cap the number of results and offset to skip documents — together they implement cursor-free pagination:
collection_group_find() — Cross-Parent Queries
collection_group_find() queries across all subcollections with the same name, regardless of which parent document they belong to. This is equivalent to Firestore’s collectionGroup() API.
_parent_path private attribute on each yielded instance is automatically set to the path of the parent document (e.g. "users/uid_123").
Collection group queries require a Firestore composite index on the
__name__ field. Create it in the Firebase console or deploy it via firestore.indexes.json before running collection group queries in production.Complete Query Example
Projections
Fetch only the fields you need to reduce bandwidth and cost.
Batch Operations
Perform atomic multi-document writes in a single round-trip.
