---
title: "Multi-properties"
description: "Learn how to define, query, and update multi-valued vertex properties in Aerospike Graph using Cardinality.list."
---

# Multi-properties

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

Aerospike Graph supports Apache TinkerPop’s model for vertex [multi-properties](https://tinkerpop.apache.org/docs/current/reference/#vertex-properties) (i.e., a vertex property with multiple values).

This page explains how to define, query, and update multi-properties using `Cardinality.list`.

::: note
“Cardinality” has two distinct meanings:  
  

On this page, “cardinality” refers to [vertex property cardinality](https://aerospike.com/docs/graph/3.1.0/develop/query/multi-properties/#updating-vertex-property-cardinality) (i.e., `single` or `list`).  
Vertex property cardinality is the number of values a single property key can have on a single vertex. Each value is a separate [VertexProperty](https://tinkerpop.apache.org/docs/current/reference/#vertex-properties) object and can itself hold properties (meta-properties). This aligns with TinkerPop’s [definition](https://tinkerpop.apache.org/javadocs/3.2.1/full/org/apache/tinkerpop/gremlin/structure/VertexProperty.Cardinality.html).  
  

This is unrelated to Aerospike’s [index cardinality](https://aerospike.com/docs/graph/3.1.0/develop/query/indexing/#cardinality), which refers to how many distinct values exist for a property key across the entire dataset. Index cardinality is used for query optimization.
:::

## Defining multi-properties

To associate multiple values with a property key on a vertex, use `VertexProperty.Cardinality.list`. Each call to `.property(...)` appends a new value.

```groovy
g.addV("person")

 .property(VertexProperty.Cardinality.list, "alias", "sam")

 .property(VertexProperty.Cardinality.list, "alias", "sammy")

 .iterate();
```

This results in a vertex with two `"alias"` values: `"sam"` and `"sammy"`. Each property value is stored independently under the same key.

## Querying multi-properties

The `.has()` step automatically matches any value stored under a multi-property.

```groovy
g.V().has("alias", "sam").toList();                       // Matches

g.V().has("alias", "sammy").toList();                     // Matches

g.V().has("alias", "sam").has("alias", "sammy").toList(); // Still matches
```

These semantics allow for concise multi-value filtering.

::: note
This behavior differs from single-valued properties where only one value can be stored at a time.
:::

## Updating vertex property cardinality

While the examples above demonstrate how to use `Cardinality.list` to store multiple property values, it’s important to understand how this differs from the default behavior.

By default, property cardinality is `single`, meaning any new value overwrites the previous one:

```groovy
g.addV("person").property("name", "alice").iterate();

g.V().has("name", "alice").property("name", "ally").iterate();

// Result: "name" is now "ally"
```

To preserve multiple values, you must explicitly use `Cardinality.list`:

```groovy
g.addV("person")

 .property(VertexProperty.Cardinality.list, "alias", "alice")

 .property(VertexProperty.Cardinality.list, "alias", "ally")

 .iterate();

// Result: both "alice" and "ally" stored under "alias"
```

Each invocation of `.property()` adds a new value without replacing the existing ones.

## Defining and querying multi-properties with meta-properties

Each multi-property value is stored as a separate object and can include its own meta-properties. These meta-properties are attached to individual property values—not to the vertex itself. For example:

```groovy
g.addV("person")

 // livedIn = "San Francisco", with two meta-properties: year = 2023 and season = Spring

 .property(VertexProperty.Cardinality.list, "livedIn", "San Francisco", "year", "2023", "season", "Spring")

 // livedIn = "Seattle", with two meta-properties: year = 2024 and season = Summer

 .property(VertexProperty.Cardinality.list, "livedIn", "Seattle", "year", "2024", "season", "Summer")

 // livedIn = "San Francisco", with two meta-properties: year = 2025 and season = Winter

 .property(VertexProperty.Cardinality.list, "livedIn", "San Francisco", "year", "2025", "season", "Winter")

 .iterate();
```

Meta-properties like `"year"` or `"season"` can be queried using `.properties()`:

```groovy
g.V().properties("livedIn").has("year", "2024").value().toList();   // Returns "Seattle"

g.V().properties("livedIn").has("season", "Winter").value().toList(); // Returns "San Francisco"
```

This pattern is useful when you need to differentiate between multiple values of the same property using additional contextual data.