> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cardinality

> The `cardinality` property in the Nextedy POWERSHEET data model defines the multiplicity of relationships between entity types.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

<Note title="Powersheet-Only Concept">
  Cardinality is a Powersheet data model concept. Polarion link roles do not have a cardinality setting -- Powersheet uses the `cardinality` value to control how the sheet renders and navigates relationship data.
</Note>

## Cardinality Property

| Name          | Type     | Default         | Description                                                                    |
| ------------- | -------- | --------------- | ------------------------------------------------------------------------------ |
| `cardinality` | `string` | None (required) | Defines the relationship multiplicity between the `from` and `to` entity types |

The `cardinality` property is declared within each entry of the `relationships` array in the data model YAML. It works together with `from`, `to`, `storage`, `linkRole`, `direct`, and `back` to form a complete relationship definition.

## Supported Cardinality Values

| Value          | From Side         | To Side           | Description                                               |
| -------------- | ----------------- | ----------------- | --------------------------------------------------------- |
| `one-to-many`  | Single entity     | Multiple entities | Each source entity links to multiple target entities      |
| `many-to-one`  | Multiple entities | Single entity     | Multiple source entities link to one target entity        |
| `many-to-many` | Multiple entities | Multiple entities | Multiple source entities link to multiple target entities |

<Note title="one-to-one Not Supported">
  The `one-to-one` cardinality value is not currently supported. To model a strict 1:1 relationship, use `many-to-one` and enforce the single-target constraint through workflow or validation.
</Note>

## How the Three Configuration Layers Connect

The data model, sheet sources, and sheet columns are connected through navigation property names. The cardinality of a relationship determines which expand pattern and column binding syntax to use.

* **Data model** defines entity types and relationships (including `cardinality`, `direct`, and `back` navigation property names)
* **Sheet sources** define how to query and expand those relationships using the navigation property names
* **Sheet columns** define how to display the resulting data using binding paths derived from the same navigation property names

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-WiVljKlDztH36bB/powersheet/diagrams/reference/data-model/cardinality/diagram-1.svg?fit=max&auto=format&n=-WiVljKlDztH36bB&q=85&s=a25c5e1673a67d64671faa536bd5acf9" alt="diagram" style={{ width: "620px", maxWidth: "100%" }} width="620" height="200" data-path="powersheet/diagrams/reference/data-model/cardinality/diagram-1.svg" />
</Frame>

## Shared Data Model for Examples

All examples on this page use the following minimal data model:

```yaml theme={null}
domainModelTypes:
  Chapter:
    polarionType: heading

  UserNeed:
    polarionType: user_need
    properties:
      description:
      severity:

  SystemRequirement:
    polarionType: sys_req
    properties:
      description:
      severity:

  DesignRequirement:
    polarionType: des_req
    properties:
      description:

relationships:
  - from: UserNeed
    to: Chapter
    cardinality: many-to-one
    storage: linkedWorkItems
    linkRole: parent
    direct:
      name: chapter
    back:
      name: userNeeds

  - from: SystemRequirement
    to: UserNeed
    cardinality: many-to-many
    storage: linkedWorkItems
    linkRole: decomposes
    direct:
      name: userNeeds
    back:
      name: systemRequirements
```

## Many-to-One (N:1)

**Scenario:** Each `UserNeed` belongs to exactly one `Chapter`.

The relationship uses the `direct` direction with `name: chapter` (singular, scalar navigation property). Because the cardinality is `many-to-one`, the navigation property on the "from" side points to a single entity.

### Relationship Definition

```yaml theme={null}
- from: UserNeed
  to: Chapter
  cardinality: many-to-one
  storage: linkedWorkItems
  linkRole: parent
  direct:
    name: chapter
  back:
    name: userNeeds
```

### Source Configuration

```yaml theme={null}
sources:
  - id: user_needs
    query:
      from: UserNeed
    expand:
      - name: chapter
```

The expand uses the `direct` navigation property name `chapter`. Because it is a scalar property (N:1), the expand resolves to a single related entity per row.

### Column Configuration

```yaml theme={null}
columns:
  title:
    title: Title
    hasFocus: true
  chapter:
    title: Chapter
    display: title
    list:
      search:
        - title
  chapter.title:
    title: Chapter Title
    isReadOnly: true
```

| Column Key      | Behavior                      | Description                                                                                                                                                      |
| --------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chapter`       | Single-value reference picker | Scalar navigation property renders as a dropdown picker. The `display` property controls the displayed label. The `list.search` array defines searchable fields. |
| `chapter.title` | Read-only display             | Dot-notation accesses a property on the referenced entity. Set `isReadOnly: true` to prevent editing.                                                            |

<Tip title="Scalar vs. Collection">
  A singular navigation property name (e.g., `chapter`) indicates a N:1 cardinality. The sheet renders this as a single-value reference picker, not an expandable child level.
</Tip>

## One-to-Many (1:N)

**Scenario:** Each `Chapter` has multiple child `UserNeed` items.

This is the **reverse side** of the many-to-one relationship above. It uses the `back` direction with `name: userNeeds` (plural, collection navigation property).

### Relationship Definition

The same relationship entry is used -- the 1:N perspective is simply the `back` direction of the N:1 relationship:

```yaml theme={null}
- from: UserNeed
  to: Chapter
  cardinality: many-to-one
  storage: linkedWorkItems
  linkRole: parent
  direct:
    name: chapter
  back:
    name: userNeeds
```

When querying from `Chapter`, the `back.name` value `userNeeds` provides the collection navigation property.

### Source Configuration

```yaml theme={null}
sources:
  - id: chapters
    query:
      from: Chapter
    expand:
      - name: userNeeds
```

The expand uses the `back` navigation property name `userNeeds`. Because it is a collection property (1:N), the expand creates child rows underneath each `Chapter`.

### Column Configuration

```yaml theme={null}
columns:
  title:
    title: Chapter
    hasFocus: true
  userNeeds:
    title: Title
    hasFocus: true
```

| Column Key  | Behavior            | Description                                                                                                                |
| ----------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `userNeeds` | Child row expansion | Collection navigation property expands into a new hierarchical level in the sheet. Each child row displays one `UserNeed`. |

<Note title="No Dot-Notation for Expansion">
  When a collection navigation property is used as a column key, it opens a new sheet level with child rows. No dot-notation is needed -- the expand directly opens the child level.
</Note>

## Many-to-Many (M:N)

**Scenario:** `UserNeed` items are linked to multiple `SystemRequirement` items, and vice versa.

Many-to-many relationships use an **association entity** as an intermediate layer. The source expand is two levels deep, and column binding uses dot-notation to reach through the association to the target entity.

### Relationship Definition

```yaml theme={null}
- from: SystemRequirement
  to: UserNeed
  cardinality: many-to-many
  storage: linkedWorkItems
  linkRole: decomposes
  direct:
    name: userNeeds
  back:
    name: systemRequirements
```

### Source Configuration

```yaml theme={null}
sources:
  - id: user_needs
    query:
      from: UserNeed
    expand:
      - name: systemRequirements
        expand:
          - name: systemRequirement
```

The expand is **two levels**:

1. `systemRequirements` -- navigates to the association entity (collection)
2. `systemRequirement` -- navigates from the association to the actual target entity (scalar)

### Column Configuration

```yaml theme={null}
columns:
  title:
    title: Title
    hasFocus: true
  systemRequirements.systemRequirement:
    title: System Requirement
    list:
      search:
        - objectId
        - title
      createNew: true
  systemRequirements.systemRequirement.title:
    title: SysReq Title
    hasFocus: true
```

| Column Key                                   | Behavior                    | Description                                                                                                                                                                 |
| -------------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `systemRequirements.systemRequirement`       | Multi-item reference picker | Two-level dot-notation traverses association then target. Renders as a multi-item picker. `list.search` enables search; `createNew: true` allows creating new linked items. |
| `systemRequirements.systemRequirement.title` | Display field on target     | Three-level dot-notation accesses a property on the target entity through the association.                                                                                  |

<Warning title="Two-Level Expand Required">
  M:N relationships always require a two-level expand in the source configuration. If you omit the inner expand (`- name: systemRequirement`), the column will bind to the association entity rather than the target entity, and data will not display correctly.
</Warning>

## Navigation Property Naming Conventions

The navigation property names declared in `direct` and `back` follow consistent naming conventions that signal the cardinality:

| Direction | Cardinality Side | Naming Convention   | Example                           |
| --------- | ---------------- | ------------------- | --------------------------------- |
| `direct`  | N:1 (scalar)     | Singular, camelCase | `chapter`, `systemRequirement`    |
| `direct`  | M:N (collection) | Plural, camelCase   | `userNeeds`, `riskControls`       |
| `back`    | 1:N (collection) | Plural, camelCase   | `userNeeds`, `designRequirements` |
| `back`    | M:N (collection) | Plural, camelCase   | `systemRequirements`, `hazards`   |

<Tip title="Naming Signals Cardinality">
  Singular navigation property names (e.g., `chapter`) indicate scalar references (N:1). Plural names (e.g., `userNeeds`) indicate collections (1:N or M:N). Consistent naming makes sheet configurations easier to read and debug.
</Tip>

## Relationship Context Properties

Each relationship entry that includes a `cardinality` value also requires the following sibling properties:

| Property      | Type     | Required | Description                                                                                            |
| ------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `from`        | `string` | Yes      | Source entity type name. Must match a key in `domainModelTypes`.                                       |
| `to`          | `string` | Yes      | Target entity type name. Must match a key in `domainModelTypes`.                                       |
| `cardinality` | `string` | Yes      | One of: `one-to-many`, `many-to-one`, `many-to-many`.                                                  |
| `storage`     | `string` | Yes      | Storage mechanism. Typically `linkedWorkItems` for Polarion link-based relationships.                  |
| `linkRole`    | `string` | Yes      | Polarion link role identifier (e.g., `parent`, `refines`, `derives_from`, `decomposes`, `mitigates`).  |
| `direct`      | `object` | Yes      | Forward navigation direction. Contains `name` (the navigation property name from `from` to `to`).      |
| `back`        | `object` | Yes      | Reverse navigation direction. Contains `name` (the navigation property name from `to` back to `from`). |

The `direct` and `back` objects each contain a `name` property that defines the navigation property used in source expands and column binding paths.

## Cardinality Summary

| Cardinality | Model                                                        | Source Expand                                                 | Column Binding                         | UI Behavior                   |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1**     | `cardinality: many-to-one`, `direct.name: chapter`           | `- name: chapter`                                             | `chapter`, `chapter.title`             | Single-value reference picker |
| **1:N**     | Reverse of N:1, `back.name: userNeeds`                       | `- name: userNeeds`                                           | `userNeeds`                            | Child rows (new sheet level)  |
| **M:N**     | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker   |

## Complete YAML Example

A full data model demonstrating all cardinality patterns with the standard RTM entity set:

```yaml theme={null}
domainModelTypes:
  UserNeed:
    polarionType: user_need
    properties:
      description:
      severity:

  SystemRequirement:
    polarionType: sys_req
    properties:
      description:
      severity:

  DesignRequirement:
    polarionType: des_req
    properties:
      description:

  Hazard:
    polarionType: hazard
    properties:
      description:

  RiskControl:
    polarionType: risk_control
    properties:
      description:

relationships:
  # N:1 — each SystemRequirement derives from one UserNeed
  - from: SystemRequirement
    to: UserNeed
    cardinality: many-to-one
    storage: linkedWorkItems
    linkRole: refines
    direct:
      name: userNeed
    back:
      name: systemRequirements

  # 1:N — each UserNeed has many SystemRequirements (reverse of above)
  # No separate entry needed; use the back direction of the N:1 above.

  # N:1 — each DesignRequirement derives from one SystemRequirement
  - from: DesignRequirement
    to: SystemRequirement
    cardinality: many-to-one
    storage: linkedWorkItems
    linkRole: derives_from
    direct:
      name: systemRequirement
    back:
      name: designRequirements

  # M:N — Hazards linked to multiple RiskControls and vice versa
  - from: Hazard
    to: RiskControl
    cardinality: many-to-many
    storage: linkedWorkItems
    linkRole: mitigates
    direct:
      name: riskControls
    back:
      name: hazards
```

## Related Pages

* [Relationships](/powersheet/reference/data-model/relationships) -- Full relationship definition reference
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- Direct and back direction details
* [Link Roles](/powersheet/reference/data-model/link-roles) -- Polarion link role configuration
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- Entity type definitions
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- Column binding path syntax
* [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) -- Configuring columns for M:N relationships
* [Sources](/powersheet/reference/sheet-config/sources) -- Sheet source and expand configuration
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- Query expand clause reference

<LastReviewed date="2026-07-02" />
