Skip to main content
An embedded object is a value type stored directly inside its parent collection document. Unlike a root collection, an embedded object has no ID of its own and no independent lifecycle — it is always read and written together with the parent. Use embedded objects for structured data that belongs to a single parent record, such as a postal address inside an order or a recipient list inside an email.

Declaring an Embedded Object

Annotate the nested class with @embedded or @Embedded() and use it as a field type in your root collection.
Order is the root collection. Address is stored inside each order document — there is no separate addresses collection or join step.
Embedded classes are not passed to Cindel.open as schema entries. Only root collection schemas go in the schema list. The generator registers embedded types through their parent collection automatically.

Key Constraints

Embedded objects are intentionally simpler than root collections. Keep these limits in mind when modeling:

No own ID

Embedded objects do not have a dbId field. They are identified by their position inside the parent document.

No independent CRUD

You cannot call get, put, delete, or filter directly on an embedded class. All persistence goes through the parent collection.

No indexes on embedded fields

Cindel does not support @Index on fields of an embedded class. Place indexes on root collection fields when you need indexed lookup.

No nested lists

A List field inside an embedded object cannot itself contain a List. For deeper nesting, use additional embedded classes as list element types.

Nullable and List Variants

Embedded fields can be nullable or collected into a list.

Nullable Embedded Field

List of Embedded Objects

Each element in the list is stored as a full embedded document inside the parent record.

Nested Embedding

An embedded object can itself contain another embedded object. This lets you model structured hierarchies up to any depth, as long as no level contains a nested list.
Email is the root. Recipient is stored inside each email. RecipientMetadata is stored inside each recipient.

Filtering on Embedded Fields

The generated query API provides typed helpers that navigate embedded field paths. You do not need to write raw path strings for common queries.

Filter a Single Embedded Object

Filter Nested Embedded Objects

Filter a List of Embedded Objects by Element

The generated helpers match the Dart field names of each embedded class, so renaming a field (while keeping its stored @Name) keeps your Dart code consistent.

Embedded vs. Linked Root Collection

Choosing between an embedded object and a linked root collection comes down to lifecycle and sharing:
A good rule of thumb: if you would describe the nested value as belonging to the parent (a shipping address belongs to an order), embed it. If you would describe the relationship as connecting two independent things (a song connects to an artist), use a root collection with a CindelLink.