Skip to main content
By default, every query fetches the complete document from Firestore — all fields, regardless of whether your application actually uses them. Projections let you tell Firestore exactly which fields to return, transferring only the data you need. In Firestore Pydantic ODM, a projection is a plain pydantic.BaseModel class whose field names define the mask. You pass it to find() or find_one() and the returned instances are of that projection type, not the original model type.

How Projections Work

When you provide a projection class to find() or find_one(), the ODM inspects the class’s field definitions and calls Firestore’s .select() API with only those field names. Firestore’s server then strips all other fields before sending the response over the wire. Each document yielded by find() is constructed as an instance of your projection class, not the original model. This means you get a lean, validated object with only the fields you requested.
Firestore bills per document read, not per byte transferred. However, projections reduce the payload size of each response, which decreases network latency and egress costs — especially important for large documents or high-throughput services.

Defining a Projection Model

A projection model is a regular pydantic.BaseModel (not a BaseFirestoreModel) with one field per Firestore attribute you want to retrieve. Field names must match the Firestore document field names exactly, or you can use Pydantic’s alias= to map a different Python name to the underlying Firestore field.
When a field in your projection has an alias, the ODM uses the alias as the Firestore field name in the field mask. This ensures the .select() call requests the correct Firestore column even if your Python attribute has a different name.

Using projection= in find()

Pass your projection class to the projection= keyword argument of find(). You can combine it with any filters, ordering, and pagination parameters:

Using projection= in find_one()

find_one() accepts the same projection= parameter and returns an instance of the projection class (or None):

Return Type is the Projection Class

The yielded or returned objects are instances of the projection class, not the original model. Keep this in mind for type annotations and downstream logic:
Because projection instances are plain BaseModel objects, they do not have Firestore methods like .save(), .update(), or .delete(). If you need to modify a document after fetching its projection, use User.get(summary.id) to load the full model instance first — but only if you include id in your projection.

Including id in a Projection

The ODM always populates the id field from doc.id when constructing instances. To access the document ID on a projection, simply add id: Optional[str] = None to your projection class:

Projections with Aliases

When your model stores Firestore field names that differ from your Python attribute names (using Pydantic’s alias=), your projection must use the same alias to ensure the field mask is correct:

Complete Projection Example

Querying

Explore the full filter, ordering, and pagination API.

FirestoreField API

Reference for the descriptor that powers field-level filter expressions.