Konnektr Logo
Concepts

Querying the Graph

AgeDigitalTwins supports two query languages:

  1. Azure Digital Twins Query Language: Refer to the official documentation.
  2. Cypher: Built on Apache AGE, Cypher queries provide powerful graph querying capabilities.

The used query language is automatically detected based on the query syntax.

Cypher Query Language for Digital Twins

Basic Queries

  • Find all twins:

    MATCH (t:Twin) RETURN t;
  • Find relationships:

    MATCH (t:Twin)-[r]->(m:Model) RETURN t, r, m;

Using digitaltwins.is_of_model

  • Find twins of a specific model:

    MATCH (t:Twin) WHERE digitaltwins.is_of_model(t, 'dtmi:com:adt:dtsample:room;1') RETURN t;

ADT Query Functions and Cypher Equivalents

ADT Query FunctionCypher Equivalent
IS_OF_MODELdigitaltwins.is_of_model
STARTSWITHSTARTS WITH
ENDSWITHENDS WITH
CONTAINSCONTAINS
IS_NULLIS NULL
IS_DEFINEDIS NOT NULL

Parameterized Queries

Cypher queries support parameterized placeholders ($param) to safely pass dynamic values:

HTTP API

Include a parameters object in the request body:

{
  "query": "MATCH (t:Twin) WHERE t.temperature > $minTemp RETURN t",
  "parameters": {
    "minTemp": 25.0
  }
}

Parameters support the following value types:

  • Primitives: strings, numbers, booleans, null
  • Arrays: lists of values (e.g. ["a", "b", "c"])
  • Objects: nested maps/dictionaries (e.g. {"color": "blue", "size": 100})

SDK Usage

Pass a dictionary as the second argument to QueryAsync<T>:

var result = await client.QueryAsync<JsonDocument>(
    "MATCH (t:Twin { `$dtId`: $id }) RETURN t",
    new Dictionary<string, object?> { { "id", "myTwinId" } }
).FirstOrDefaultAsync();

Continuation Tokens

Parameters are automatically embedded in continuation tokens for pagination. You only need to supply parameters on the first request; subsequent pages reuse them transparently.

For more examples, refer to the QueryTests.cs and AdtQueryToCypherTests.cs.

The /entities alias

Every route under /digitaltwins is also served under /entities, by the same handlers: the path is rewritten before routing, so the bodies, status codes, auth policies and rate limits are identical — they are not two implementations.

# identical responses
curl http://localhost:8080/digitaltwins/room-1
curl http://localhost:8080/entities/room-1

# queries still use the ADT dialect either way
curl -X POST http://localhost:8080/query -H 'Content-Type: application/json' \
  -d '{"query": "SELECT * FROM DIGITALTWINS WHERE $dtId = '\''room-1'\''"}'

Use it when the domain has no digital-twin vocabulary. The payloads do not change: $dtId and $metadata.$model are the same on both paths, and FROM DIGITALTWINS remains the query dialect. The alias is not listed in the OpenAPI document, so generated clients see a single canonical surface.

On this page