Skip to main content
Most queries return full typed objects, and that is the right choice whenever your app needs to display, edit, or write those objects back. Projections are different: instead of hydrating complete records, they read only the fields you ask for. Aggregates go one step further and calculate a single summary value — a count, minimum, maximum, sum, or average — without reading any individual records into application code at all. Use projections to keep lightweight lists and autocomplete fast; use aggregates for dashboard summaries and numeric totals.

Single-Property Projections

Generated property helpers project one persisted field from a query result. Call the helper after your query conditions and execute with findAll() or findFirst().
Use findFirst() when only the first projected value is needed:
Combine with normal query conditions, sorting, and pagination just as you would with a full-object query:

Dynamic Property Projection

When the field name is only known at runtime, use the lower-level property<T> API:
Prefer generated property helpers whenever the field is known at compile time. Use property<T>('fieldName') only for dynamic code that already works with persisted field names.

Multi-Property Projections

Use properties([...]) to project several persisted fields at once. The result is a List<CindelDocument>, where each entry is a Map<String, Object?> keyed by the persisted field names you requested.
Multi-property projections are a good fit for table views, autocomplete lists, export previews, and summary screens that only need a handful of fields per record.
Pass persisted field names to properties([...]). If a model field is annotated with @Name, its persisted name may differ from the Dart field name. Generated single-property helpers handle this automatically when the field is known at compile time.

Aggregates

Aggregate helpers are available on any property query. Chain them in place of findAll() or findFirst() to receive a single computed value.

count()

count() counts non-null projected values. Use query-level count() (without a property) when you want to count the matching objects themselves:

min() and max()

min() and max() require comparable values (dates, numbers, strings):

sum() and average()

sum() and average() require numeric values:

Combining Aggregates with Filters

All aggregates compose naturally with filters. Apply conditions before the property projection:
Combine projections and aggregates with where() filters for best performance. Starting from an indexed lookup narrows the candidate set before the projection or aggregate runs.

Common Use Cases

Choosing the Right Query Shape

Use this decision guide to pick the right approach for each screen or operation:
CindelDocument (Map<String, Object?>) is the map-shaped type returned by multi-property projections. Most application code should prefer typed objects and generated helpers unless you are intentionally working with a partial projection.