

# AWS IoT TwinMaker knowledge graph
Knowledge graph

The AWS IoT TwinMaker knowledge graph organizes all the information contained within your AWS IoT TwinMaker workspaces and presents it in a visual graph format. You can run queries against your entities, components, and component types to generate visual graphs that show you the relationships between your AWS IoT TwinMaker resources.

The following topics show you how to use and integrate the knowledge graph.

**Topics**
+ [

## AWS IoT TwinMaker knowledge graph core concepts
](#tm-knowledge-graph-concepts)
+ [

# How to Run AWS IoT TwinMaker knowledge graph queries
](tm-knowledge-graph-use.md)
+ [

# Knowledge graph scene integration
](tm-knowledge-graph-scene.md)
+ [

# How to use AWS IoT TwinMaker knowledge graph with Grafana
](tm-knowledge-Grafana-panel.md)
+ [

# AWS IoT TwinMaker knowledge graph additional resources
](tm-knowledge-graph-resources.md)

## AWS IoT TwinMaker knowledge graph core concepts


This topic covers the key concepts and vocabulary of the knowledge graph feature.

**How knowledge graph works**:  
Knowledge graph creates relationships between entities and their components with the existing [CreateEntity](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_CreateEntity.html) or [ UpdateEntity](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_UpdateEntity.html) APIs. A relationship is just a property of a special data type [ RELATIONSHIP](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_DataType.html#:~:text=Valid%20Values%3A-,RELATIONSHIP,-%7C%20STRING%20%7C%20LONG%20%7C%20BOOLEAN) that is defined on a component of an entity. AWS IoT TwinMaker knowledge graph calls the [ExecuteQuery](https://docs.aws.amazon.com/iot-twinmaker/latest/apireference/API_ExecuteQuery.html) API to make a query based on any data in the entities or the relationships between them. Knowledge graph uses the flexible PartiQL query language (used by many AWS services) that has newly added graph match syntax support to help you write your queries. After the calls are made, you can view the results as a table or visualize them as a graph of connected nodes and edges.

**Knowledge graph key terms**:  
+ **Entity graph**: A collection of nodes and edges within a workspace.
+ **Node**: Every entity in your workspace becomes a node in the entity graph.
+ **Edge**: Every relationship property defined on a component of an entity becomes an edge in the entity graph. In addition, a hierarchical parent-child relationship defined using the parentEntityId field of an entity also becomes an edge in the entity graph with an "isChildOf" relationship name. All edges are directional edges.
+ **Relationship**: An AWS IoT TwinMaker Relationship is a special type of property of an Entity’s component. You can use the AWS IoT TwinMaker [ CreateEntity](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_CreateEntity.html) or [UpdateEntity](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_UpdateEntity.html) API to define and edit a relationship. In AWS IoT TwinMaker, a relationship must be defined in a component of an entity. A relationship cannot be defined as an isolated resource. A relationship must be directional from one entity to another.

# How to Run AWS IoT TwinMaker knowledge graph queries
Using knowledge graph

Before you use the AWS IoT TwinMaker knowledge graph, make sure you have completed the following prerequisites:
+ Create an AWS IoT TwinMaker workspace. You can create a workspace in the [AWS IoT TwinMaker console](https://console.aws.amazon.com/iottwinmaker/).
+ Become familiar with AWS IoT TwinMaker's entity-component system and how to create entities. For more information, see [Create your first entity](twinmaker-gs-entity.md).
+ Become familiar with AWS IoT TwinMaker's data connectors. For more information, see [AWS IoT TwinMaker data connectors](data-connector-interface.md).

**Note**  
In order to use the AWS IoT TwinMaker knowledge graph, you need to be in either the **standard** or **tiered bundle** pricing modes. For more information, see [Switch AWS IoT TwinMaker pricing modes](tm-pricing-mode.md).

The following procedures show you how to write, run, save, and edit queries.

 **Open the query editor**   

**To navigate to the knowledge graph query editor**

1. Open the [AWS IoT TwinMaker console](https://console.aws.amazon.com/iottwinmaker/).

1. Open the workspace in which you wish to use knowledge graph.

1. In the left navigation menu, choose **Query editor**.

1. The query editor opens. You are now ready to run queries on your workspace's resources.

 **Run a query**   

**To run a query and generate a graph**

1. In the query editor, choose the **Editor** tab to open the syntax editor.

1. In the editor space, write the query you wish to run against your workspace's resources.  
![\[The editor space with a query entered.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/kg-query-updated.png)

   In the example shown, the request searches for entities that contain `vav_%` in their name, then organizes these entities by the `feed` relationship between them, using the following code.

   ```
   SELECT ahu, vav, r FROM EntityGraph
   MATCH (vav)<-[r:feed]-(ahu)
   WHERE vav.entityName LIKE 'vav_%'
   ```
**Note**  
The knowledge graph syntax uses [PartiQL](https://partiql.org/). For information on this syntax, see [AWS IoT TwinMaker knowledge graph additional resources](tm-knowledge-graph-resources.md).

1. Choose **Run query** to run the request you created.

   A graph is generated based on your request.  
![\[A graph showing the results of the query detailed in the preceding steps.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/tm-kg-graph-output.png)

   The example graph shown above is based on the query example in step 2.

1. The results of the query are also presented in a list. Choose **results** to view the query results in a list.

1. Optionally, choose **Export as** to export the query results in JSON or CSV format.

This covers the basic use of knowledge graph in the console. For more information and examples demonstrating the knowledge graph syntax, see [AWS IoT TwinMaker knowledge graph additional resources](tm-knowledge-graph-resources.md).

# Knowledge graph scene integration
Generate a scene graph

You can use AWS IoT app kit components to build a web application that integrates knowledge graph into your AWS IoT TwinMaker scenes. This allows you to generate graphs based on the 3D nodes (the 3D models which represent your equipment or systems) that are present within your scene. To create an application that graphs 3D nodes from your scene, first bind the 3D nodes to entities in your workspace. With this mapping, AWS IoT TwinMaker graphs the relationships between the 3D models present in your scene and the entities in your workspace. Then you can create a web application, select 3D models with your scene, and explore their relationships to other entities in a graph format.

![\[A TwinMaker scene with a knowledge graph showing the relationships between 3D models.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/intro_kg_scene.png)


For an example of a working web application that utilizes the AWS IoT app kit components to generate graphs in an AWS IoT TwinMaker scene, see the [AWS IoT TwinMaker sample react app](https://github.com/awslabs/iot-app-kit/blob/3DKG_Demo/examples/react-app/src/components/index.tsx) on github.

## AWS IoT TwinMaker scene graph prerequisites


Before you create a web app that uses AWS IoT TwinMaker knowledge graph in your scenes, complete the following prerequisites:
+ Create an AWS IoT TwinMaker workspace. You can create a workspace in the [AWS IoT TwinMaker console](https://console.aws.amazon.com/iottwinmaker/).
+ Become familiar with AWS IoT TwinMaker's entity-component system and how to create entities. For more information, see [Create your first entity](twinmaker-gs-entity.md).
+ Create an AWS IoT TwinMaker scene populated with 3D models.
+ Become familiar with AWS IoT TwinMaker's AWS IoT app kit components. For more information on the AWS IoT TwinMaker components, see [Create a customized web application using AWS IoT TwinMaker UI Components](tm-app-kit.md).
+ Become fimalliar with knowledge graph concepts and key terminology. See [AWS IoT TwinMaker knowledge graph core concepts](tm-knowledge-graph.md#tm-knowledge-graph-concepts).

**Note**  
To use the AWS IoT TwinMaker knowledge graph and any related features, you need to be in either the **standard** or **tiered bundle** pricing modes. For more information on AWS IoT TwinMaker pricing, see [Switch AWS IoT TwinMaker pricing modes](tm-pricing-mode.md).

## Bind 3D nodes in your scene


Before you create a web app that integrates knowledge graph with your scene, bind the 3D models, referred to as 3D nodes, that are present in your scene to the associated workspace entity. For example, if you have a model of mixer equipment in a scene, and a corresponding entity called `mixer_0`, create a **data binding** between the model of the mixer and the entity representing the mixer– so that the model and entity can be graphed.

**To perform a data binding action**

1. Log in to the [AWS IoT TwinMaker console](https://console.aws.amazon.com/iottwinmaker/).

1. Open your workspace and select a scene with the 3D nodes you wish to bind.

1. Select a node (3D model) in the scene composer. When you select a node, it will open an inspector panel on the right side of the screen.

1. In the inspector panel, navigate to the top of the panel and select the **\$1** button. Then choose the **Add entity binding** option. This will open a drop-down where you can select an entity to bind to your currently selected node.  
![\[A scene with the plus sign selected in the Inspector panel and Add entity binding highlighted.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/binding-step-4.png)

1. From the data binding drop-down menu, select the entity id you want to map to the 3D model. For the **Component name** and **Property name** fields, select the components and properties you want to bind.  
![\[A scene with the Component and Property Names selected in the Inspector panel.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/binding-step-6.png)

   Once you have made selections for the **Entity Id**, **Component Name** and **Property Name** fields, the binding is complete.

1. Repeat this process for all models and entities you want to graph.
**Note**  
The same data binding operation can be performed on your scene tags, simply select a tag instead of an entity and follow the same process to bind the tag to a node.

## Create a web application


After you bind your entities, use the AWS IoT app kit library to build a web app with a knowledge graph widget that lets you view your scene and explore the relationships between your scene nodes and entities.

Use the following resources to create your own app:
+ The AWS IoT TwinMaker sample react app github [ Readme](https://github.com/awslabs/iot-app-kit/blob/3DKG_Demo/examples/react-app/README.md) documentation.
+ The AWS IoT TwinMaker sample react app [ source](https://github.com/awslabs/iot-app-kit/blob/3DKG_Demo/examples/react-app/src/components/index.tsx) on github.
+ The AWS IoT app kit [ Getting started](https://awslabs.github.io/iot-app-kit/?path=/docs/overview-getting-started--docs) documentation.
+ The AWS IoT app kit [ Video Player component](https://awslabs.github.io/iot-app-kit/?path=/docs/components-videoplayer--docs) documentation.
+ The AWS IoT app kit [Scene Viewer component](https://awslabs.github.io/iot-app-kit/?path=/docs/components-sceneviewer--docs) documentation.

The following procedure demonstrates the functionality of the scene viewer component in a web app.

**Note**  
This procedure is based on the implementation of the AWS IoT app kit scene viewer component in the AWS IoT TwinMaker sample react app.

1. Open the scene viewer component of the AWS IoT TwinMaker sample react app. In the search field type an entity name or partial entity name (case sensitive search) then select the **Search** button. If a model is bound to the entity id, then the model in the scene will be highlighted and a node of the entity will be shown in the scene viewer panel.  
![\[A scene with the Knowledge Graph scene viewer panel displayed.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/search_select_kg_event.png)

1. To generate a graph of all relationships, select a node in the scene viewer widget and select the **Explore** button.  
![\[A scene with the Knowledge Graph scene viewer panel displaying a graph of relationships.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/explore_select_kg.png)

1. Press the **Clear** button to clear your current graph selection and start over.

# How to use AWS IoT TwinMaker knowledge graph with Grafana
Knowledge graph Grafana panel

This section shows you how to add a query editor panel to your AWS IoT TwinMaker Grafana dashboard to run and display queries.

## AWS IoT TwinMaker query editor prerequisites
AWS IoT TwinMaker query editor prerequisites

Before you use the AWS IoT TwinMaker knowledge graph in Grafana, complete the following prerequisites:
+ Create an AWS IoT TwinMaker workspace. You can create a workspace in the [AWS IoT TwinMaker console](https://console.aws.amazon.com/iottwinmaker/).
+ Configure AWS IoT TwinMaker for use with Grafana. For instructions, see [AWS IoT TwinMaker Grafana dashboard integration](grafana-integration.md).

**Note**  
To use the AWS IoT TwinMaker knowledge graph, you need to be in either the **standard** or **tiered bundle** pricing modes. For more information, see [Switch AWS IoT TwinMaker pricing modes](tm-pricing-mode.md).

## AWS IoT TwinMaker query editor permissions
Knowledge graph Grafana permissions

To use the AWS IoT TwinMaker query editor in Grafana, you must have an IAM role with permission for the action `iottwinmaker:ExecuteQuery`. Add that permission to your workspace dashboard role, as shown in this example:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket",
                "arn:aws:s3:::amzn-s3-demo-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iottwinmaker:GetEntity",
                "iottwinmaker:ListEntities",
                "iottwinmaker:ExecuteQuery"
            ],
            "Resource": [
                "arn:aws:iottwinmaker:us-east-2:111122223333:workspace/workspaceId",
                "arn:aws:iottwinmaker:us-east-2:111122223333:workspace/workspaceId/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "iottwinmaker:ListWorkspaces",
            "Resource": "*"
        }
    ]
}
```

------

**Note**  
When you configure your AWS IoT TwinMaker Grafana data source, make sure to use the role with this permission for the **Assume role ARN** field. After you add it, you can select your workspace from the dropdown next to **Workspace**.

For more information, see [Creating a dashboard IAM role](dashboard-IAM-role.md#dashboard-IAM-role.title).

### Set up the AWS IoT TwinMaker query editor panel
Knowledge graph Grafana panel

**To set up a new Grafana dashboard panel for knowledge graph**

1. Open your AWS IoT TwinMaker Grafana dashboard.

1. Create a new **dashboard panel**. For detailed steps on how to create a panel, see [ Create a dashboard](https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/create-dashboard/) in the Grafana documentation.

1. From the list of visualizations, select **AWS IoT TwinMaker Query Editor**.  
![\[The dropdown list in the AWS IoT TwinMaker dashboard contains the option for the AWS IoT TwinMaker Query Editor.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/tw-query-editor-dropdown.png)

1. Select the data source to run queries against.

1. **(Optional)** Add a name for the new panel in the provided field.

1. Select **Apply** to save and confirm your new panel.

The knowledge graph panel works in a similar way as the query editor provided in the AWS IoT TwinMaker console. You can run, write, and clear queries you make in the panel. For more information on how to write queries, see [AWS IoT TwinMaker knowledge graph additional resources](tm-knowledge-graph-resources.md).

#### How to use the AWS IoT TwinMaker query editor
Use the query editor

The results of your queries are displayed in three ways, as shown in the following images: visualized in a graph, listed in a table, or presented as a run summary.
+ **Graph visualization:**  
![\[AWS IoT TwinMaker query editor results displayed as a Visual graph.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/kg-vis-graph.png)

  The visual graph only displays data for queries that have at least one relation in the result. The graph displays entities as nodes and relationships as directed edges in the graph.
+ **Tabular data:**  
![\[AWS IoT TwinMaker query editor results displayed as tabular data.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/kg-table-data.png)

  The tabular data format displays the data for all queries. You can search the table for specific results or subsets of the results. The data can be exported in JSON or CSV format.
+ **Run summary**  
![\[AWS IoT TwinMaker query editor results displayed as a run summary.\]](http://docs.aws.amazon.com/iot-twinmaker/latest/guide/images/kg-run-sum.png)

  The run summary displays the query and metadata about the status of the query.

# AWS IoT TwinMaker knowledge graph additional resources
Knowledge graph additional resources

This section provides basic examples of the PartiQL syntax used to write queries in the knowledge graph, as well as links to PartiQL documentation that provide information on the knowledge graph data model.
+ [ PartiQL graph data model documentation](https://partiql.org/gpml/graph_model.html)
+ [ PartiQL graph query documentation](https://partiql.org/gpml/graph_query.html)

This set of examples shows basic queries with their responses. Use this as a reference to write your own queries.

**Basic queries**  
+ **Get all entities with a filter**

  ```
  SELECT entity
  FROM EntityGraph MATCH (entity)
  WHERE entity.entityName = 'room_0'
  ```

   This query returns all the entities in a workspace with the name `room_0`.

  `FROM` clause: `EntityGraph` is the graph collection that contains all the entities and their relationships in a workspace. This collection is automatically created and managed by AWS IoT TwinMaker based on the entities in your workspace.

  `MATCH` clause: specifies a pattern that matches a portion of the graph. In this case, the pattern `(entity)` matches every node in the graph and is bound to the entity variable. The `FROM` clause must be followed by the `MATCH` clause.

  `WHERE` clause: specifies a filter on the `entityName` field of the node, where the value must match `room_0`.

  `SELECT` clause: specifies the `entity` variable so the whole entity node is returned.

  **Response:**

  ```
  {
    "columnDescriptions": [
      {
        "name": "entity",
        "type": "NODE"
      }
    ],
    "rows": [
      {
        "rowData": [
          {
            "arn": "arn:aws:iottwinmaker:us-east-1: 577476956029: workspace / SmartBuilding8292022 / entity / room_18f3ef90 - 7197 - 53 d1 - abab - db9c9ad02781 ",
            "creationDate": 1661811123914,
            "entityId": "room_18f3ef90-7197-53d1-abab-db9c9ad02781",
            "entityName": "room_0",
            "lastUpdateDate": 1661811125072,
            "workspaceId": "SmartBuilding8292022",
            "description": "",
            "components": [
              {
                "componentName": "RoomComponent",
                "componentTypeId": "com.example.query.construction.room",
                "properties": [
                  {
                    "propertyName": "roomFunction",
                    "propertyValue": "meeting"
                  },
                  {
                    "propertyName": "roomNumber",
                    "propertyValue": 0
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
  ```

  The `columnDescriptions` returns metadata about the column, such as the name and type. The type returned is `NODE`. This indicates that the whole node has been returned. Other values for the type can be `EDGE` which would indicate a relationship or `VALUE` which would indicate a scalar value such as an integer or string.

  The `rows` returns a list of rows. As only one entity was matched, one `rowData` is returned which contains all the fields in an entity.
**Note**  
Unlike SQL where you can only return scalar values, you can return an object (as JSON) using PartiQL.

  Each node contains all the entity-level fields such as `entityId`, `arn` and `components`, component-level fields such as `componentName`, `componentTypeId` and `properties` as well as property-level fields such as `propertyName` and `propertyValue`, all as a nested JSON.
+ **Get all relationships with a filter**:

  ```
  SELECT relationship
  FROM EntityGraph MATCH (e1)-[relationship]->(e2)
  WHERE relationship.relationshipName = 'isLocationOf'
  ```

  This query returns all the relationships in a workspace with relationship name `isLocationOf`.

   The `MATCH` clause: specifies a pattern that matches two nodes (indicated by `()`) that are connected by a directed edge (indicated by `-[]->`) and bound to a variable called `relationship`.

  The `WHERE` clause: specifies a filter on the `relationshipName` field of the edge, where the value is `isLocationOf`.

  The `SELECT` clause: specifies the relationship variable so the whole edge node is returned.

  **Response**

  ```
  {
      "columnDescriptions": [{
          "name": "relationship",
          "type": "EDGE"
      }],
      "rows": [{
          "rowData": [{
              "relationshipName": "isLocationOf",
              "sourceEntityId": "floor_83faea7a-ea3b-56b7-8e22-562f0cf90c5a",
              "targetEntityId": "building_4ec7f9e9-e67e-543f-9d1b- 235df7e3f6a8",
              "sourceComponentName": "FloorComponent",
              "sourceComponentTypeId": "com.example.query.construction.floor"
          }]
      },
          ... //rest of the rows are omitted
      ]
  }
  ```

  The type of the column in `columnDescriptions` is an `EDGE`.

  Each `rowData` represents an edge with fields like `relationshipName`. This is the same as the relationship property name defined on the entity. The `sourceEntityId`, `sourceComponentName` and `sourceComponentTypeId` give information about which entity and component the relationship property was defined on. The `targetEntityId` specifies which entity this relationship is pointing towards.
+ **Get all entities with a specific relationship to a specific entity**

  ```
  SELECT e2.entityName
        FROM EntityGraph MATCH (e1)-[r]->(e2)
        WHERE relationship.relationshipName = 'isLocationOf'
        AND e1.entityName = 'room_0'
  ```

  This query returns all the entity names of all entities that have an `isLocationOf` relationship with the `room_0` entity.

  The `MATCH` clause: specifies a pattern that matches any two nodes (`e1`, `e2`) that have a directed edge (`r`).

  The `WHERE` clause: specifies a filter on the relationship name and source entity’s name.

  The `SELECT` clause: returns the `entityName` field in the `e2` node.

  **Response**

  ```
  {
    "columnDescriptions": [
      {
         "name": "entityName",
         "type": "VALUE"
      }
    ],
     "rows": [
      {
         "rowData": [
           "floor_0"
        ]
      }
    ]
  }
  ```

  In the columnDescriptions, the type of the column is `VALUE` since `entityName` is a string.

  One entity, `floor_0`, is returned.

**MATCH**  
The following patterns are supported in a `MATCH` clause:  
+ Match node 'b' pointing to node 'a':

  ```
  FROM EntityGraph MATCH (a)-[rel]-(b)
  ```
+ Match node 'a' pointing to node 'b':

  ```
  FROM EntityGraph MATCH (a)-[]->(b)
  ```

  There is no variable bound to a relationship assuming a filter doesn’t need to be specified on the relationship.
+ Match node 'a' pointing to node 'b' and node 'b' pointing to node 'a':

  ```
  FROM EntityGraph MATCH (a)-[rel]-(b)
  ```

  This will return two matches: one from 'a' to 'b' and another from 'b' to 'a', so the recommendation is to use directed edges wherever possible.
+ The relationship name is also a label of the property graph `EntityGraph`, so you can simply specify the relationship name following a colon (:) instead of specifying a filter on `rel.relationshipName` in the `WHERE` clause.

  ```
  FROM EntityGraph MATCH (a)-[:isLocationOf]-(b)
  ```
+ Chaining: patterns can be chained to match on multiple relationships.

  ```
  FROM EntityGraph MATCH (a)-[rel1]->(b)-[rel2]-(c)
  ```
+ Variable hop patterns can span multiple nodes and edges as well:

  ```
  FROM EntityGraph MATCH (a)-[]->{1,5}(b)
  ```

  This query matches any pattern with outgoing edges from node 'a' within 1 to 5 hops. The allowed quantifiers are:

  `{m,n}` - between m and n repetitions

  `{m,}` - m or more repetitions.

**FROM**:  
An entity node can contain nested data, such as components which themselves contain further nested data such as properties. These can be accessed by unnesting the result of the MATCH pattern.  

```
SELECT e
FROM EntityGraph MATCH (e), e.components AS c, c.properties AS p
WHERE c.componentTypeId = 'com.example.query.construction.room',
AND p.propertyName = 'roomFunction'
AND p.propertyValue = 'meeting'
```
Access nested fields by dotting `.` into a variable. A comma (,) is used to unnest (or join) entities with the components inside and then the properties inside those components. `AS` is used to bind a variable to the unnested variables so that they can be used in the `WHERE` or `SELECT` clauses. This query returns all entities that contains a property named `roomFunction` with value `meeting` in a component with component type id `com.example.query.construction.room`   
To access multiple nested fields of a field such as multiple components in an entity, use the comma notation to do a join.  

```
SELECT e
FROM EntityGraph MATCH (e), e.components AS c1, e.components AS c2
```

**SELECT**:  
+ Return a node:

  ```
  SELECT e
  FROM EntityGraph MATCH (e)
  ```
+ Return an edge:

  ```
  SELECT r
  FROM EntityGraph MATCH (e1)-[r]->(e2)
  ```
+ Return a scalar value:

  ```
  SELECT floor.entityName, room.description, p.propertyValue AS roomfunction
  FROM EntityGraph MATCH (floor)-[:isLocationOf]-(room),
  room.components AS c, c.properties AS p
  ```

  Format the name of the output field by aliasing it using `AS`. Here, instead of `propertyValue` as column name in the response, `roomfunction` is returned.
+ Return aliases:

  ```
  SELECT floor.entityName AS floorName, luminaire.entityName as luminaireName
  FROM EntityGraph MATCH (floor)-[:isLocationOf]-(room)-[:hasPart]-
  (lightingZone)-[:feed]-(luminaire)
  WHERE floor.entityName = 'floor_0'
  AND luminaire.entityName like 'lumin%'
  ```

  Using aliases is highly recommended to be explicit, increase readability, and avoid any ambiguities in your queries.

**WHERE**:  
+ The supported logical operators are `AND`, `NOT`, and `OR`.
+ The supported comparison operators are `<`, `<=`, `>`, `=>`,`=`, and `!=`.
+ Use the `IN` keyword if you want to specify multiple `OR` conditions on the same field.
+ Filter on an entity, component or property field:

  ```
  FROM EntityGraph MATCH (e), e.components AS c, c.properties AS p
  WHERE e.entityName = 'room_0'
  AND c.componentTypeId = 'com.example.query.construction.room',
  AND p.propertyName = 'roomFunction'
  AND NOT p.propertyValue = 'meeting'
  OR p.propertyValue = 'office'
  ```
+ Filter on the `configuration` property. Here `unit` is the key in the configuration map and `Celsius` is the value.

  ```
  WHERE p.definition.configuration.unit = 'Celsius'
  ```
+ Check if a map property contains a given key and value:

  ```
  WHERE p.propertyValue.length = 20.0
  ```
+ Check if a map property contains a given key:

  ```
  WHERE NOT p.propertyValue.length IS MISSING
  ```
+ Check if a list property contains a given value:

  ```
  WHERE 10.0 IN p.propertyValue
  ```
+ Use the `lower()` function for case insensitive comparisons. By default, all comparisons are case sensitive.

  ```
  WHERE lower(p.propertyValue) = 'meeting'
  ```

**LIKE**:  
Useful if you do not know the exact value for a field and can perform full text search on the specified field. `%` represents zero or more.  

```
WHERE e.entityName LIKE '%room%'
```
+ Infix search: `%room%`
+ Prefix search: `room%`
+ Suffix search: `%room`
+ If you have '%' in your values, then put an escape character in the `LIKE` and specify the escape character with `ESCAPE`.

```
WHERE e.entityName LIKE 'room\%' ESCAPE '\'
```

**DISTINCT**:  

```
SELECT DISTINCT c.componentTypeId
FROM EntityGraph MATCH (e), e.components AS c
```
+ The `DISTINCT` keyword eliminates duplicates from the final result.

  `DISTINCT` is not supported on complex data types.

**COUNT**  

```
SELECT COUNT(e), COUNT(c.componentTypeId)
FROM EntityGraph MATCH (e), e.components AS c
```
+ The `COUNT` keyword computes the number of items in a query result.
+ `COUNT` is not supported on nested complex fields and graph pattern fields.
+ `COUNT` aggregation is not supported with `DISTINCT` and nested queries.

  For example, `COUNT(DISTINCT e.entityId)` is not supported.

**PATH**  
The following pattern projections are supported in querying using path projection:  
+ Variable hop queries

  ```
  SELECT p FROM EntityGraph MATCH p = (a)-[]->{1, 3}(b)
  ```

  This query matches and projects nodes metadata of any patterns with outgoing edges from node *a* within 1 to 3 hops.
+ Fixed hop queries

  ```
  SELECT p FROM EntityGraph MATCH p = (a)-[]->(b)<-[]-(c)
  ```

  This query matches and projects metadata of entities and incoming edges to *b*.
+ Undirected queries

  ```
  SELECT p FROM EntityGraph MATCH p = (a)-[]-(b)-[]-(c)
  ```

  This query matches and projects the metadata of nodes in 1 hop patterns connecting *a* and *c* via *b*.

  ```
  {
      "columnDescriptions": [
          {
              "name": "path",
              "type": "PATH"
          }
      ],
      "rows": [
          {
              "rowData": [
                  {
                      "path": [
                          {
                              "entityId": "a",
                              "entityName": "a"
                          },
                          {
                              "relationshipName": "a-to-b-relation",
                              "sourceEntityId": "a",
                              "targetEntityId": "b"
                          },
                          {
                              "entityId": "b",
                              "entityName": "b"
                          }
                      ]
                  }
              ]
          },
          {
              "rowData": [
                  {
                      "path": [
                          {
                              "entityId": "b",
                              "entityName": "b"
                          },
                          {
                              "relationshipName": "b-to-c-relation",
                              "sourceEntityId": "b",
                              "targetEntityId": "c"
                          },
                          {
                              "entityId": "c",
                              "entityName": "c"
                          }
                      ]
                  }
              ]
          }
      ]
  }
  ```

  This `PATH` query response comprises of only metadata that identifies all the nodes and edges of each path/pattern between *a* and *c* via *b*.

**LIMIT** and **OFFSET**:  

```
SELECT e.entityName
FROM EntityGraph MATCH (e)
WHERE e.entityName LIKE 'room_%'
LIMIT 10
OFFSET 5
```
`LIMIT` specifies the number of results to be returned in the query, and `OFFSET` specifies the number of results to skip.

**LIMIT** and **maxResults**:  
The following example shows a query that returns 500 results in total, but only displays 50 at a time per API call. This pattern can be used where you need to limit the amount of displayed results, for example if you are only able to display 50 results in a UI.  

```
aws iottwinmaker execute-query \
--workspace-id exampleWorkspace \
--query-statement "SELECT e FROM EntityGraph MATCH (e) LIMIT 500"\
--max-results 50
```
+ The `LIMIT` keyword affects the query and limits the resulting rows. If you need to control the number of results returned per API call without limiting the total number of returned results, use `LIMIT`.
+ `max-results` is an optional parameter for the [ExecuteQuery API action](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_ExecuteQuery.html). `max-results` only applies to the API and how results are read within the bounds of the above query.

  Using `max-results` in a query allows you to reduce the number of displayed results without limiting the actual number of returned results.
The query below iterates through the next page of results. This query uses the `ExecuteQuery` API call to return rows 51-100, where the next page of results is specified by the `next-token`– in this case the token is: `"H7kyGmvK376L"`.  

```
aws iottwinmaker execute-query \
--workspace-id exampleWorkspace \
--query-statement "SELECT e FROM EntityGraph MATCH (e) LIMIT 500"\
--max-results 50
--next-token "H7kyGmvK376L"
```
+ The `next-token` string specifies the next page of results. For more information, see the [ ExecuteQuery](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_ExecuteQuery.html#API_ExecuteQuery_RequestSyntax) API action.

AWS IoT TwinMaker knowledge graph query has the following limits: 


****  

| Limit Name | Quota | Adjustable | 
| --- | --- | --- | 
|  Query execution timeout  | 10 seconds | No | 
|  Maximum number of hops  | 10 | Yes | 
|  Maximum number of self `JOIN`s  | 20 | Yes | 
|  Maximum number of projected fields  | 20 | Yes | 
|  Maximum number of conditional expressions (`AND`, `OR`, `NOT`)  | 10 | Yes | 
|  Maximum length of a `LIKE` expression pattern (including wildcards and escapes)  | 20 | Yes | 
| Maximum number of items that can be specified in an IN clause | 10 | Yes | 
| Maximum value for OFFSET | 3000 | Yes | 
|  Maximum value for `LIMIT`  | 3000 | Yes | 
|  Maximum value for traversals (`OFFSET` \$1 `LIMIT`)  | 3000 | Yes | 