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

# Properties sheet reference

> Complete reference for properties sheet fields and syntax in the NEAT physical data model.

The properties sheet has two property types: `Connection` and `Data`. `Connection` specifies how nodes are connected; `Data` specifies the data stored on the node. These map to `Entity` and `Literal` in semantic modeling. Use `PascalCase` for views; NEAT uses `camelCase` for data properties. Check the `Value Type` column to distinguish them.

## Data property

A data property specifies the data stored on the node (node attributes). The following table shows an example.

| View        | View property | Value type                | Container      | Container property |
| ----------- | ------------- | ------------------------- | -------------- | ------------------ |
| WindTurbine | capacity      | float64(unit=power:megaw) | GeneratingUnit | capacity           |

This specifies that `WindTurbine` has a `capacity` property of type float64 (unit `power:megaw`), stored in the `GeneratingUnit` container.

For supported value types, see the [Containers API](/api-reference/concepts/20230101/containers). The `container.properties.type.type` field specifies the property type.

Two `Value Type` options support extra parameters:

* `float32` and `float64` — Specify floating-point numbers. Use the `unit` parameter for the unit. See [Units](/cdf/deploy/neat/data_modeling/excel/physical/units) for available units.
* `enum` — Specify an enumeration. Set `collection` to the enumeration name and, optionally, `unknownValue` for unknown values. A corresponding `enum` sheet with values is required in the physical data model file.

| View        | View property | Value type                                      | Container   | Container property |
| ----------- | ------------- | ----------------------------------------------- | ----------- | ------------------ |
| WindTurbine | category      | enum(collection=category, unknownValue=onshore) | WindTurbine | category           |

### Index

For data properties, you can specify an index to speed up queries. The following table shows the syntax.

| View        | View property | Value type | Container      | Container property | Index                            |
| ----------- | ------------- | ---------- | -------------- | ------------------ | -------------------------------- |
| WindTurbine | name          | text       | GeneratingUnit | name               | btree:nameIndex(cursorable=True) |

You can specify whether the index is cursorable. See [Performance considerations](/cdf/dm/dm_guides/dm_performance_considerations#pagination-cursorable-indexes).

To index multiple properties, use the same `Index` name for each and specify the property order.

| View        | View property | Value type | Container      | Container property | Index                               |
| ----------- | ------------- | ---------- | -------------- | ------------------ | ----------------------------------- |
| WindTurbine | name          | text       | GeneratingUnit | name               | inverted:nameCapacityIndex(order=1) |
| WindTurbine | capacity      | float64    | GeneratingUnit | capacity           | inverted:nameCapacityIndex(order=2) |

Two index types: `btree` for non-list properties, `inverted` for list properties. Omit the type to default to `btree` (non-list) or `inverted` (list).

| View        | View property | Value type | Container      | Container property | Index              |
| ----------- | ------------- | ---------- | -------------- | ------------------ | ------------------ |
| WindTurbine | tags          | text       | GeneratingUnit | name               | inverted:tagsIndex |

### Constraint

Use constraints to restrict values stored in a property or container. Constraints ensure data integrity and reflect the real world.

CDF supports two constraint types:

* `uniqueness`: Ensures values of a property or set of properties are unique within the container. Set `bySpace` to apply uniqueness per space.
* `requires`: Points to another container; the instance must have data there to populate this container.

Use this short-form syntax for constraints in NEAT, as with indexes:

```text theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
<constraint_type>:<constraint_id>(<param1>=<value1>,<param2>=<value2>, ...)
```

In the Properties sheet, you can set the `uniqueness` constraint on a property. The following table shows an example.

| View           | View property | Value type | Container      | Container property | Constraint                                    |
| -------------- | ------------- | ---------- | -------------- | ------------------ | --------------------------------------------- |
| GeneratingUnit | serialNumber  | text       | GeneratingUnit | serialNumber       | uniqueness:serialUnq(bySpace=True)            |
| WindTurbine    | serialNumber  | text       | GeneratingUnit | serialNumber       | uniqueness:idUnique(bySpace=True, order=1)    |
| WindTurbine    | internalId    | text       | GeneratingUnit | internalId         | uniqueness:serialNoUnq(bySpace=True, order=2) |

The `bySpace` parameter applies uniqueness per space. For multiple properties, use the `order` parameter to specify property significance, as with indexes.

Set `requires` constraints in the Containers sheet. The following table shows an example.

| Container      | Name           | Description                     | Constraint                           |
| -------------- | -------------- | ------------------------------- | ------------------------------------ |
| GeneratingUnit | GeneratingUnit | Container for generating units. | requires:power(container=PowerPlant) |

For the `requires` constraint, the `container` parameter specifies which container must have data to populate this one. For multiple containers, list all constraints in the Constraint column:

| Container      | Name           | Description                     | Constraint                                                                                     |
| -------------- | -------------- | ------------------------------- | ---------------------------------------------------------------------------------------------- |
| GeneratingUnit | GeneratingUnit | Container for generating units. | requires:power(container=PowerPlant), requires:describe(container=cdf\_cdm:CogniteDescribable) |

## Connection property

All connections have a `Value type` that specifies the type of the connected node. The following table shows an example.

| View        | View property | Connection | Value type | Max Count |
| ----------- | ------------- | ---------- | ---------- | --------- |
| WindTurbine | blades        | direct     | Blade      | 3         |

This connection specifies that `WindTurbine` has a `blades` property that is a direct relation to the `Blade` view. The `Max Count` column specifies that there can be at most 3 blades connected to a wind turbine. If `Max Count` is not specified, there is no upper limit on the number of connections.

### Connection implementation

The `Connection` column specifies how the connection is implemented in CDF and can be:

* **Direct relation** — Low storage and query cost
* **Edge connection** — More flexible but higher storage and query cost
* **Reverse connection** — Points to the other end of a direct relation or edge

For details, see [data modeling documentation](/cdf/dm/dm_concepts/dm_spaces_instances#direct-relations-vs-edges). Direct relations have an upper limit of 1000 connections per node.

The following shows the syntax:

* `direct` — Direct relation. No extra parameters. Specify `Container` and `Container property` because direct connections are stored in the container.
* `edge` — Edge connection. Optional: `type`, `properties`, `direction`
* `reverse` — Reverse connection. Specify the `property` being reversed.

**Edge example**:

| View        | View property | Connection                                                 | Value type             | Max Count |
| ----------- | ------------- | ---------------------------------------------------------- | ---------------------- | --------- |
| WindTurbine | metmasts      | edge(type=distance,properties=Distance,direction=outwards) | MetMast                | inf       |
| Distance    | distance      |                                                            | float64(unit=length:m) | 1         |

This specifies that `WindTurbine` has a `metmasts` property that is an edge connection to `MetMast`. The edges use type `distance` and store properties in the `Distance` view. The `Distance` view has a `distance` property of type float64 (unit `length:m`).

Why are both `type` and `properties` needed? The `type` specifies the edge type for filtering when querying. The `properties` parameter specifies which properties are stored on the edge. For example, you can query all MetMast (Weather Station) nodes connected to a WindTurbine within 100 meters.

**Reverse example**:

| View    | View property | Connection                 | Value type  | Max Count |
| ------- | ------------- | -------------------------- | ----------- | --------- |
| MetMast | windTurbines  | reverse(property=metmasts) | WindTurbine | inf       |

This specifies that `MetMast` has a `windTurbines` property that reverses the `metmasts` property in `WindTurbine`. The `Max Count` column indicates multiple wind turbines can connect to a MetMast.

Tying to the edge example above, this reverse is an edge pointing the opposite direction of `WindTurbine`.`metmasts`. Reverse connections let you reuse the same edge for both directions.
