Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.helix-db.com/llms.txt

Use this file to discover all available pages before exploring further.

For the complete documentation index optimized for AI agents, see llms.txt.
Secondary indexes accelerate property-based filtering on the labeled property graph. Two flavors are available, each on both nodes and edges:
  • Equality indexes map property = value to the set of matching IDs. Use them for exact-match lookups like “all users with status = active.”
  • Range indexes provide ordered scans over numeric and string properties. Use them for comparisons like timestamp > T or score >= 4.
Secondary indexes are opt-in. They speed up reads at the cost of additional write overhead and storage. Only index properties that are frequently filtered on. Unindexed properties remain queryable via .where_(Predicate::...), but the route will scan the label rather than seek the index. The DSL fragments below are bare traversals. To execute them, wrap each one in a read_batch() or write_batch() route as shown in Querying.

Equality Index — Nodes

Declare the index as part of your schema setup write batch:
g().create_index_if_not_exists(
    IndexSpec::node_equality("User", "status"),
)
Insert a node carrying the indexed property:
g().add_n(
    "User",
    vec![
        ("userId", PropertyInput::from("u-42")),
        ("status", PropertyInput::from("active")),
    ],
)
Query through the index using the source-predicate form. n_with_label_where pushes the predicate down to the index so the route never scans the full label:
g().n_with_label_where(
    "User",
    SourcePredicate::eq("status", "active"),
)

Equality Index — Edges

Declare an equality index on an edge property:
g().create_index_if_not_exists(
    IndexSpec::edge_equality("FOLLOWS", "since_year"),
)
Create an edge between two known nodes. add_e is called from a node-state traversal — the current node is the edge’s source, and the second argument is the target:
g().n(NodeRef::param("source"))
    .add_e(
        "FOLLOWS",
        NodeRef::param("target"),
        vec![("since_year", PropertyInput::from(2024i64))],
    )
Query the edge index directly with e_with_label_where:
g().e_with_label_where(
    "FOLLOWS",
    SourcePredicate::eq("since_year", 2024i64),
)

Range Index — Nodes

Declare a range index on a numeric or string property:
g().create_index_if_not_exists(
    IndexSpec::node_range("Event", "timestamp"),
)
Range indexes use the same insert path as equality indexes; the property values are simply ordered by the index. Query with any of gt, gte, lt, lte, or between:
g().n_with_label_where(
    "Event",
    SourcePredicate::gt("timestamp", 1_700_000_000i64),
)

Range Index — Edges

g().create_index_if_not_exists(
    IndexSpec::edge_range("RATED", "score"),
)
g().e_with_label_where(
    "RATED",
    SourcePredicate::gte("score", 4i64),
)

See Also

For tenant-scoped equality lookups using the same secondary-index machinery, see Multi-Tenancy.