{"info":{"_postman_id":"9dc4fc1c-5fa8-48cb-a82d-9111faacc238","name":"NGSI-LD Relationships using Linked Data","description":"This tutorial discusses relationships between linked data entities and how the concepts of **JSON-LD** and **NGSI-LD**\ncan be used to interrogate entities and navigate from one entity to another. The tutorial discusses a series of simple\nlinked-data data models based around the supermarket chain’s store finder application, and demonstrates how to design\nmodels holding one-to-one, one-to-many and many-to-many relationships. This **NGSI-LD** tutorial is a direct analogue to\nthe earlier _Understanding Entities and Relationships_ tutorial (which was based on the **NGSI v2** interface). The\ndifferences in relationships created using **NSGI v2** and **NGSI-LD** are highlighted and discussed in detail.\n\nThe `docker-compose` file for this tutorial can be found on GitHub: \n\n![GitHub](https://fiware.github.io/tutorials.Relationships-Linked-Data/icon/GitHub-Mark-32px.png) [FIWARE 602: Relationships using Linked Data](https://github.com/Fiware/tutorials.Relationships-Linked-Data)\n\n\nAll NGSI data entity attributes can be divided into one of two types.\n\n-   _Property_ attributes\n-   _Relationship_ attributes\n\nFor each entity, the _Property_ attributes (including various subtypes such as _GeoProperty_ , _TemporalProperty_ and\ntime values) define the current state something in the real world. As the state of the entity changes the `value` of\neach _Property_ is updated to align with the last real world reading of the the attribute. All _Property_ attributes\nrelate to the state of a single entity.\n\n_Relationship_ attributes correspond to the interactions **between** entities (which are expected to change over time).\nThey effectively provide the graph linking the nodes of the data entities together. Each _Relationship_ attribute holds\nan `object` in the form of a URN - effectively a pointer to another object. _Relationship_ attributes do not hold data\nthemselves.\n\nBoth properties and relationships may in turn have a linked embedded structure (of _properties-of-properties_ or\n_properties-of-relationships or relationships-of-properties_ or _relationships-of-relationships_ etc.) which lead a full\ncomplex knowledge graph.\n\n## Designing Data Models using JSON-LD\n\nIn order for computers to be able to navigate linked data structures, proper ontologically correct data models must be\ncreated and a full `@context` must be defined and made accessible. We can do this by reviewing and updating the existing\ndata models from the NGSI v2 [Entity Relationships](https://github.com/FIWARE/tutorials.Entity-Relationships) tutorial.\n\n### Revision: Data Models for a Stock management system as defined using NGSI-v2\n\nAs a reminder, four types of entity were created in the NGSI v2 stock management system. The relationship between the\nfour NGSI v2 entity models was defined as shown below:\n\n![](https://fiware.github.io/tutorials.Relationships-Linked-Data/img/entities-v2.png)\n\nMore details can be found in the NGSI v2\n[Entity Relationships](https://github.com/FIWARE/tutorials.Entity-Relationships) tutorial.\n\nIn NGSI v2 relationship attributes are just standard properties attributes. By convention NGSI v2 relationship\nattributes are given names starting `ref` and are defined using the `type=\"Relationship\"`. However, this is merely\nconvention and may not be followed in all cases. There is no infallible mechanism for detecting which attributes are\nassociative relationships between entities.\n\n### Data Models for a Stock management system defined using NGSI-LD\n\nThe richer [JSON-LD](https://json-ld.org/spec/FCGS/json-ld/20130328) description language is able to define NSGI-LD\nentities by linking entities directly as shown below.\n\n![](https://fiware.github.io/tutorials.Relationships-Linked-Data/img/entities-ld.png)\n\nThe complete data model must be understandable by both developers and machines.\n\n-   A full Human readable definition of this data model can be found\n    [online](https://fiware.github.io/tutorials.Step-by-Step/schema).\n-   The machine readable JSON-LD defintion can be found at\n    [`https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld`](https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld) -\n    this file will be used to provide the `@context` to power our NGSI-LD data entities.\n\nFour data models have been created for this NGSI-LD stock management system. The relationships between the models are\ndescribed below:\n\n-   The [**Store** model](https://fiware.github.io/tutorials.Step-by-Step/schema/Store/) is now based on and extends the\n    FIWARE\n    [**Building** model](https://fiware-datamodels.readthedocs.io/en/latest/Building/Building/doc/spec/index.html). This\n    ensures that it offers standard properties for `name`, `address` and category.\n    -   A Building will hold `furniture` this is a 1-many relationship.\n        -   Building :arrow_right: Shelf.\n-   The [**Shelf** model](https://fiware.github.io/tutorials.Step-by-Step/schema/Shelf/) is a custom data model defined\n    for the tutorial\n    -   Each **Shelf** is `locatedIn` a **Building**. This is a 1-1 relationship. It is the reciprical relationship to\n        `furniture` defined above.\n        -   Shelf :arrow_right: Building.\n    -   A **Shelf** is `installedBy` a **Person** - this is a 1-1 relationship. A shelf knows who installed it, but it\n        is this knowledge is not part of the Person entity itself.\n        -   Shelf :arrow_right: Person\n    -   A **Shelf** `stocks` a given **Product**. This is another 1-1 relationship, and again it is not recipricated. A\n        **Product** does not know which **Shelf** it is to be found on.\n        -   Shelf :arrow_right: Product\n-   A [**StockOrder** model](https://fiware.github.io/tutorials.Step-by-Step/schema/StockOrder/) replaces the\n    **Inventory Item** bridge table defined for NGSI v2 :\n    -   A **StockOrder** is `requestedBy` a **Person** - this is a 1-1 relationship.\n        -   StockOrder :arrow_right: Person.\n    -   A **StockOrder** is `requestedFor` a **Building** - this is a 1-1 relationship.\n        -   StockOrder :arrow_right: Building.\n    -   A **StockOrder** is a request for a specific `orderedProduct` - this 1-1 relationship.\n        -   StockOrder :arrow_right: Product.\n-   The [**Product** model](https://fiware.github.io/tutorials.Step-by-Step/schema/Product/) remains unchanged. It has\n    no relationships of its own.\n\nAdditionally some relationships have been defined to be linked to `https://schema.org/Person` entities. This could be\noutlinks to a separate HR system for example.\n\n## Comparison between Linked and Non-Linked Data Systems\n\nObviously within a single isolated Smart System itself, it makes no difference whether a rich, complex linked-data\narchitecture is used or a simpler, non-linked-data system is created. However if the data is designed to be shared, then\nlinked data is a requirement to avoid data silos. An external system is unable to \"know\" what relationships are unless\nthey have been provided in a machine readable form.\n\n### Video: Rich Snippets: Product Search\n\nA simple example of an external system interogating for structured data can be found in online product search. Machines\nfrom third parties such as Google are able to read product information (encoded using a standard\n[**Product** data model](https://jsonld.com/product/)) and display a rich snippet of product information with a standard\nstar rating.\n\n[![](http://img.youtube.com/vi/_-rRxKSm2ic/0.jpg)](https://www.youtube.com/watch?v=_-rRxKSm2ic \"Rich Snippets\")\n\nClick on the image above to watch an introductory video on rich snippets for product search.\n\nFurther machine readable data model examples can be found on the [Steal Our JSON-LD](https://jsonld.com/) website.\n\n## Traversing relationships\n\n> **Example**: Imagine the scenario where a pallet of Products are moved from stock in the warehouse (`stockCount`) onto\n> the shelves of the store (`storeCount`) . How would NGSI v2 and NGSI-LD computations differ?\n\n### Relationships without Linked Data\n\nWithout linked data, there is no machine readable way to connect entities together. Every data relationship must be\nknown in advanced somehow. Within an isolated Smart System this is not an issue, since the architect of the system will\nknow in advance _what-connects-to-what_.\n\nFor example in the simple NGSI v2 Entity Relationships tutorial, a convenience bridge table **InventoryItem** entity had\nbeen created specifically to hold both count on the shelf and count in the warehouse in a single entity. In any\ncomputation only the **InventoryItem** entity would be involved. The `stockCount` value would be decremented and the\n`shelfCount` value would incremented. In the NGSI v2 model both the `storeCount` and the `shelfCount` have been placed\ninto the conceptual **InventoryItem** Entity. This is a necessary workaround for NGSI v2 and it allows for simpler data\nreading and data manipulation. However technically it is ontologically incorrect, as there is no such thing as an\n**InventoryItem** in the real world, it is really two separate ledgers, products bought for the store and products sold\non the shelf, which in turn have an indirect relationship.\n\nSince the entity data is not yet machine readable externally, the programmer is free to design models as she sees fit\nand can decide to update two attributes of one **InventoryItem** Entity or two separate attributes on two separate\n**Shelf** and **StockOrder** entities without regards as to whether these really are real concrete items in the real\nworld. However this means **external systems** cannot discover information for themselves and must be pre-programmed to\nknow where information is held.\n\n### Relationships with Linked Data\n\nWith a well defined data model using linked data, every relationship can be predefined in advance and is discoverable.\nUsing [JSON-LD](https://json-ld.org/spec/FCGS/json-ld/20130328) concepts (specifically `@graph` and `@context`) it is\nmuch easier for computers to understand indirect relationships and navigate between linked entities. Due to hese\nadditional annotations it is possible to create usable models which are ontologically correct and therefore **Shelf**\ncan now be directly assigned a `numberOfItems` attribute and bridge table concept is no longer required. This is\nnecessary as other systems may be interogating **Shelf** directly.\n\nSimilarly a real **StockOrder** Entity can be created which holds a entry of which items are currently on order for each\nstore. This is a proper context data entity as `stockCount` describes the current state of a product in the warehouse.\nOnce again this describes a single, real world entity and is ontologically correct.\n\nUnlike the NGSI v2 scenario, with linked data, it would be possible for an **external system** to discover relationships\nand interogate our Supermarket. Imagine for example, an\n[Autonomous Mobile Robot](https://www.intorobotics.com/40-excellent-autonomous-mobile-robots-on-wheels-that-you-can-build-at-home/)\nsystem which is used to move a pallet of products onto a shelf it would be possible for this **external system** to\n\"know\" about our supermarket by navigating the relationships in the linked data the `@graph` from **StockOrder** to\n**Shelf** as shown:\n\n-   Some `product:XXX` items have been removed from `stockOrder:0001` - decrement `stockCount`.\n-   Interogating the **StockOrder** is discovered that the **Product** is `requestedFor` for a specific URI e.g.\n    `store:002`\n\n```json\n  \"@graph\": [\n   {\n      \"@id\": \"tutorial:orderedProduct\",\n      \"@type\": \"https://uri.etsi.org/ngsi-ld/Relationship\",\n      \"schema:domainIncludes\": [{\"@id\": \"tutorial:StockOrder\"}],\n      \"schema:rangeIncludes\": [{\"@id\": \"tutorial:Product\"}],\n      \"rdfs:comment\": \"The Product ordered for a store\",\n      \"rdfs:label\": \"orderedProduct\"\n    },\n    ...etc\n]\n```\n\n-   It is also discovered from the **StockOrder** model that the `requestedFor` URI defines a **Building**\n\n```json\n  \"@graph\": [\n    {\n      \"@id\": \"tutorial:requestedFor\",\n      \"@type\": \"https://uri.etsi.org/ngsi-ld/Relationship\",\n      \"schema:domainIncludes\": [{\"@id\": \"tutorial:StockOrder\"}],\n      \"schema:rangeIncludes\": [{\"@id\": \"fiware:Building\"}],\n      \"rdfs:comment\": \"Store for which an item is requested\",\n      \"rdfs:label\": \"requestedFor\"\n    },\n    ...etc\n]\n```\n\n-   It is discovered from the **Building** model that every **Building** contains `furniture` as an array of URIs.\n-   It is discovered from the **Building** model that these URIs represent **Shelf** units\n\n```json\n\"@graph\": [\n    {\n      \"@id\": \"tutorial:furniture\",\n      \"@type\": \"https://uri.etsi.org/ngsi-ld/Relationship\",\n      \"schema:domainIncludes\": [{\"@id\": \"fiware:Building\"}],\n      \"schema:rangeIncludes\": [{\"@id\": \"tutorial:Shelf\"}],\n      \"rdfs:comment\": \"Units found within a Building\",\n      \"rdfs:label\": \"furniture\"\n    },\n    ...etc\n]\n```\n\n-   It is discovered from the **Shelf** model that the `stocks` attribute holds a URI representing **Product** items.\n\n```json\n\"@graph\": [\n    {\n      \"@id\": \"tutorial:stocks\",\n      \"@type\": \"https://uri.etsi.org/ngsi-ld/Relationship\",\n      \"schema:domainIncludes\": [{\"@id\": \"tutorial:Shelf\"}],\n      \"schema:rangeIncludes\": [{\"@id\": \"tutorial:Product\"}],\n      \"rdfs:comment\": \"The product found on a shelf\",\n      \"rdfs:label\": \"stocks\"\n    },\n    ...etc\n]\n```\n\n-   A request the **Shelf** unit which holds the correct **Product** for the `stocks` attribute is made and the Shelf\n    `numberOfItems` attribute can be incremented.\n\nThrough creating and using standard data models and decribing the linked data properly, it would not matter to the robot\nif the underlying system were to change, provided that the Properties and Relationships resolve to fully qualified names\n(FQN) and a complete `@graph`. For example the JSON short name attributes could be amended or the relationships\nredesigned but their real intent (which resolves to a fixed FQN) could still be discovered and used.\n\n# Prerequisites\n\n## Docker\n\nTo keep things simple all components will be run using [Docker](https://www.docker.com). **Docker** is a container\ntechnology which allows to different components isolated into their respective environments.\n\n-   To install Docker on Windows follow the instructions [here](https://docs.docker.com/docker-for-windows/)\n-   To install Docker on Mac follow the instructions [here](https://docs.docker.com/docker-for-mac/)\n-   To install Docker on Linux follow the instructions [here](https://docs.docker.com/install/)\n\n**Docker Compose** is a tool for defining and running multi-container Docker applications. A\n[YAML file](https://raw.githubusercontent.com/Fiware/tutorials.Identity-Management/master/docker-compose.yml) is used\nconfigure the required services for the application. This means all container services can be brought up in a single\ncommand. Docker Compose is installed by default as part of Docker for Windows and Docker for Mac, however Linux users\nwill need to follow the instructions found [here](https://docs.docker.com/compose/install/)\n\n## Cygwin\n\nWe will start up our services using a simple bash script. Windows users should download [cygwin](http://www.cygwin.com/)\nto provide a command-line functionality similar to a Linux distribution on Windows.\n","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json"},"item":[{"name":"Obtain full Linked Data model context","id":"99f6231a-9c8f-46aa-910b-681bcf416bae","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:3004/user-context.jsonld","description":"Information about the data models and relationships used within this tutorial\ncan be obtained by requesting the full `@context` and `@graph`."},"response":[],"_postman_id":"99f6231a-9c8f-46aa-910b-681bcf416bae"},{"name":"Display all Buildings","id":"e29db1d9-4e11-486c-9109-f7402df87b02","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","type":"text","value":"<http://context/user-context.jsonld>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","disabled":true}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities?type=https://uri.fiware.org/ns/data-models%23Building&options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities"],"query":[{"key":"type","value":"https://uri.fiware.org/ns/data-models%23Building"},{"key":"options","value":"keyValues"}]},"description":"The Stores of the supermarket have been created using the FIWARE\n[**Building** model](https://fiware-datamodels.readthedocs.io/en/latest/Building/Building/doc/spec/index.html) and the\nenumerated value of this type is `fiware:Building` which expands to `https://uri.fiware.org/ns/datamodels%23Building`.\nIt is therefore possible to request all building entities without supplying a known context.\n\nThe response returns all of the existing **Building** entities, with the attributes expanded as fully qualified names\n(FQNs).\n\nAccording to the [defined data model](https://fiware.github.io/tutorials.Step-by-Step/schema/Store/):\n\n-   The `type` attribute is an `https://uri.etsi.org/ngsi-ld/type`\n-   The `name` attribute is an `https://uri.etsi.org/ngsi-ld/name`\n-   The `location` attribute is an `https://uri.etsi.org/ngsi-ld/location`\n-   The `address` attribute is an `http://schema.org/address`\n-   The `category` attribute is an `https://uri.fiware.org/ns/datamodels#category`\n\n`type`, `name` and `location` are defined in the NGSI-LD Core Context:\n[`https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld`](https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld).\nThe other attributes are defined using the Tutorial's own Context:\n[`https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld`](https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld).\nBoth `category` and `address` are _common_ attributes the defintions of which are brought in from the FIWARE data models\nand `schema.org` respectively."},"response":[],"_postman_id":"e29db1d9-4e11-486c-9109-f7402df87b02"},{"name":"Display all Products","id":"49354c21-bfc3-46b6-bbd0-26f67cebbb75","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","type":"text","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\""}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities?type=https://fiware.github.io/tutorials.Step-by-Step/schema/Product&options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities"],"query":[{"key":"type","value":"https://fiware.github.io/tutorials.Step-by-Step/schema/Product"},{"key":"options","value":"keyValues"}]},"description":"Requesting the **Product** entities can be done by supplying the FQN of the entity `type` in the request as well.\n\nHowever since the full context has been supplied in the `Link` header, the short names are returned.\n\nAccording to the [defined data model](https://fiware.github.io/tutorials.Step-by-Step/schema/Product/):\n\n-   The `type` attribute is an `https://uri.etsi.org/ngsi-ld/type`\n-   The `name` attribute is an `https://uri.etsi.org/ngsi-ld/name`\n-   The `price` attribute is an `https://fiware.github.io/tutorials.Step-by-Step/schema/price`\n-   The `size` attribute is an `https://fiware.github.io/tutorials.Step-by-Step/schema/size`\n-   The `currency` attribute is an `https://fiware.github.io/tutorials.Step-by-Step/schema/currency`\n\nThe programmatically the Product model is fully described in the\n[`https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld`](https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld)"},"response":[],"_postman_id":"49354c21-bfc3-46b6-bbd0-26f67cebbb75"},{"name":"Display all Shelves","id":"b30cd4b6-d5fb-46c9-af03-73a320259b7a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","type":"text","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\""}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities?type=Shelf&options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities"],"query":[{"key":"type","value":"Shelf"},{"key":"options","value":"keyValues"}]},"description":"Requesting the **Product** entities can be done by supplying the short of the entity `type` in the request as well,\nprovided the full context has been supplied in the `Link` header.\n\nOnce again the short names are returned.\n\nAccording to the [defined data model](https://fiware.github.io/tutorials.Step-by-Step/schema/Shelf/):\n\n-   The `type` attribute is an `https://uri.etsi.org/ngsi-ld/type`\n-   The `name` attribute is an `https://uri.etsi.org/ngsi-ld/name`\n-   The `location` attribute is an `https://uri.etsi.org/ngsi-ld/location`\n-   The `maxCapacity` attribute is an `https://fiware.github.io/tutorials.Step-by-Step/schema/maxCapacity`\n-   The `numberOfItems` attribute is an `https://fiware.github.io/tutorials.Step-by-Step/schema/numberOfItems`\n\nThe programmatically the Shelf model is fully described in the\n[`https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld`](https://fiware.github.io/tutorials.Step-by-Step/tutorials-context.jsonld)"},"response":[],"_postman_id":"b30cd4b6-d5fb-46c9-af03-73a320259b7a"},{"name":"Obtain Shelf Information","id":"7d37e79c-1e3b-425c-bd7e-91f13670cb1e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Shelf:unit001/?options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:Shelf:unit001",""],"query":[{"key":"type","value":"Shelf","description":"Entity type","disabled":true},{"key":"options","value":"keyValues","description":"* `keyValues` option in order to get a more compact and brief representation, including just attribute values\n* `values` option combined with a list of attribute values  `attrs`  for an ordered list of attributes only"}]},"description":"This example returns the context data of the *Shelf* entity with the `id=urn:ngsi-ld:Shelf:unit001`.\n\nThere are currently three additional property attributes present `location`, `maxCapacity` and `name`"},"response":[],"_postman_id":"7d37e79c-1e3b-425c-bd7e-91f13670cb1e"},{"name":"Adding 1-1 relationships","id":"ce2926bb-c332-402f-af86-7b7167252a1b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/ld+json"},{"key":"fiware-servicepath","value":"/","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"stocks\": {\n        \"type\": \"Relationship\",\n        \"object\": \"urn:ngsi-ld:Product:001\"\n    },\n    \"numberOfItems\": {\n        \"type\": \"Property\",\n        \"value\": 50\n    },\n    \"locatedIn\": {\n        \"type\": \"Relationship\",\n        \"object\": \"urn:ngsi-ld:Building:store001\",\n        \"requestedBy\": {\n            \"type\": \"Relationship\",\n            \"object\": \"urn:ngsi-ld:Person:bob-the-manager\"\n        },\n        \"installedBy\": {\n            \"type\": \"Relationship\",\n            \"object\": \"urn:ngsi-ld:Person:employee001\"\n        },\n        \"statusOfWork\": {\n            \"type\": \"Property\",\n            \"value\": \"completed\"\n        }\n    },\n    \"@context\": \"http://context/ngsi-context.jsonld\"\n}"},"url":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Shelf:unit001/attrs","description":"Within the `@context` a **Shelf** has been defined with two relationships. (`stocks` and `locatedIn`)\n\nTo create a relationship add a new attribute with `type=Relationship` and an associated `object` attribute. \\\nValue of `object` is the URN corresponding to the linked data entity.\n\n**Note** that the relationship is currently unidirectional."},"response":[],"_postman_id":"ce2926bb-c332-402f-af86-7b7167252a1b"},{"name":"Obtain the Updated Shelf","id":"0ae6c289-6c8e-4084-b028-40c778b5de35","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"},{"key":"","value":"","type":"text","disabled":true}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Shelf:unit001","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:Shelf:unit001"],"query":[{"key":"type","value":"Shelf","description":"Entity type","disabled":true}]},"description":"This example returns the context data of the *Shelf* entity with the `id=urn:ngsi-ld:Shelf:unit001`.\n\nThere are now two additional property attributes present `stocks` and `locatedIn`."},"response":[],"_postman_id":"0ae6c289-6c8e-4084-b028-40c778b5de35"},{"name":"Finding the location of a Shelf","id":"32397539-4794-4e8a-97e4-e458192283d6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Shelf:unit001/?options=keyValues&attrs=locatedIn","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:Shelf:unit001",""],"query":[{"key":"type","value":"Shelf","description":"Entity type","disabled":true},{"key":"options","value":"keyValues"},{"key":"attrs","value":"locatedIn"}]},"description":"This example returns the `locatedIn` value associated with a given `Shelf` unit. \n\nIf the `id` and `type` of a data entity are known, a specific field can be requested by using the `attrs` parameter."},"response":[],"_postman_id":"32397539-4794-4e8a-97e4-e458192283d6"},{"name":"Find the ids of all Shelf Units in a Store","id":"dd24cc0b-0d33-428e-926b-d0e686847508","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","type":"text","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\""},{"key":"Accept","name":"Accept","type":"text","value":"application/json"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/?type=Shelf&options=keyValues&q=locatedIn==\"urn:ngsi-ld:Building:store001\"&attrs=locatedIn","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities",""],"query":[{"key":"type","value":"Shelf"},{"key":"options","value":"keyValues"},{"key":"q","value":"locatedIn==\"urn:ngsi-ld:Building:store001\""},{"key":"attrs","value":"locatedIn"}]},"description":"This example returns the `locatedIn` URNs of all **Shelf** entities found within `urn:ngsi-ld:Building:store001`. This is purely an instance of using the `q` parameter to filter on attribute value"},"response":[],"_postman_id":"dd24cc0b-0d33-428e-926b-d0e686847508"},{"name":"Adding a 1-many relationship","id":"2f2a1977-dad6-4567-81e6-d0984b36e789","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/ld+json"}],"body":{"mode":"raw","raw":"{\n    \"furniture\": {\n        \"type\": \"Relationship\",\n        \"object\": [\n            \"urn:ngsi-ld:Shelf:001\",\n            \"urn:ngsi-ld:Shelf:002\"\n        ]\n    },\n    \"@context\": \"http://context/ngsi-context.jsonld\"\n}"},"url":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Building:store001/attrs","description":"To add a 1-many relationship, add an array as \nthe value of  `object` attribute. This can be used for simple links without additional data.\nThis method is used to add **Shelf** entities as `furniture` in the **Store**.\n\nThis is the reciprocal relationship to the `locatedIn` attribute on **Shelf**"},"response":[],"_postman_id":"2f2a1977-dad6-4567-81e6-d0984b36e789"},{"name":"Finding all Shelf Units found within a Store","id":"a74e7169-217d-4714-9404-d6695a0b4f80","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"},{"key":"Accept","value":"application/json","type":"text","name":"Accept"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Building:store001?options=keyValues&attrs=furniture","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:Building:store001"],"query":[{"key":"options","value":"keyValues"},{"key":"attrs","value":"furniture"}]},"description":"To find all the `furniture` within a **Building**, simply make a request to \nretrieve the `furniture` attribute. \n\nBecause the repicrocal relationship already exists,\nAdditional information can be obtained from the **Shelf** entities themselves."},"response":[],"_postman_id":"a74e7169-217d-4714-9404-d6695a0b4f80"},{"name":"Creating complex relationships","id":"aef592a7-ba5a-4aa1-9260-7c7521030c1c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/ld+json"}],"body":{"mode":"raw","raw":"{\n    \"id\": \"urn:ngsi-ld:StockOrder:001\",\n    \"type\": \"StockOrder\",\n    \"requestedFor\": {\n        \"type\": \"Relationship\",\n        \"object\": \"urn:ngsi-ld:Building:store001\"\n    },\n    \"requestedBy\": {\n        \"type\": \"Relationship\",\n        \"object\": \"urn:ngsi-ld:Person:bob-the-manager\"\n    },\n    \"orderedProduct\": {\n        \"type\": \"Relationship\",\n        \"object\": \"urn:ngsi-ld:Product:001\"\n    },\n    \"stockCount\": {\n        \"type\": \"Property\",\n        \"value\": 10000\n    },\n    \"orderDate\": {\n        \"type\": \"Property\",\n        \"value\": {\n            \"@type\": \"DateTime\",\n            \"@value\": \"2018-08-07T12:00:00Z\"\n        }\n    },\n    \"@context\": \"http://context/ngsi-context.jsonld\"\n}"},"url":"http://{{orion}}/ngsi-ld/v1/entities/","description":"To create a more complex relationship, and additional data entity must be created which holds the current state of the links between real world items.\nIn the case of the NGSI-LD data model we have already created, a **StockOrder** can be used to link **Product**, **Building** and **Person** entities and the state of the relationships between them. As well as _Relationship_ attributes,\na **StockOrder** can hold _Property_ attributes (such as the `stockCount`) and other more complex metadata such as _Properties-of-Properties_ or _Properties-of-Relationships_\n\nThe **StockOrder** is created as a standard NGSI-LD data entity."},"response":[],"_postman_id":"aef592a7-ba5a-4aa1-9260-7c7521030c1c"},{"name":"Obtain Updated Building","id":"588eb6c1-a6f1-49d8-898a-92117a9f2ad1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"},{"key":"Accept","value":"application/json","type":"text","name":"Accept","disabled":true}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:Building:store001/?options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:Building:store001",""],"query":[{"key":"options","value":"keyValues","description":"* `keyValues` option in order to get a more compact and brief representation, including just attribute values\n* `values` option combined with a list of attribute values  `attrs`  for an ordered list of attributes only"}]},"description":"This example returns the context data of the `Building` entity with the `id=urn:ngsi-ld:Building:store001`.\n\nThe response now includes the additional relationship property `furniture`, which has been added in the previous step."},"response":[],"_postman_id":"588eb6c1-a6f1-49d8-898a-92117a9f2ad1"},{"name":"Find all stores in which a product is sold","id":"b922c2da-fb24-4db0-8c8b-50b3a628894e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"","type":"text"},{"key":"Accept","value":"application/json","type":"text","name":"Accept"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/?type=StockOrder&q=orderedProduct==\"urn:ngsi-ld:Product:001\"&attrs=requestedFor&options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities",""],"query":[{"key":"type","value":"StockOrder"},{"key":"q","value":"orderedProduct==\"urn:ngsi-ld:Product:001\""},{"key":"attrs","value":"requestedFor"},{"key":"options","value":"keyValues"}]},"description":"Since _Relationship_ attributes are just like any other attribute, standard `q` parameter queries can be made on the **StockOrder** to obtain which entity relates to it. For example the query below returns an array of stores in which a given product is sold.\n\nThe query  `q==orderedProduct=\"urn:ngsi-ld:Product:001\"`  is used to filter the entities.\n\nThe response returns an array of `requestedFor` attributes in the response."},"response":[],"_postman_id":"b922c2da-fb24-4db0-8c8b-50b3a628894e"},{"name":"Find all Products sold in a Store","id":"86955fc3-cb83-49ed-ae81-6293d6440437","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Link","type":"text","value":"<{{datamodels-context.jsonld}}>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\""},{"key":"Accept","name":"Accept","type":"text","value":"application/json"}],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/?type=StockOrder&q=requestedFor==\"urn:ngsi-ld:Building:store001\"&options=keyValues&attrs=orderedProduct","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities",""],"query":[{"key":"type","value":"StockOrder"},{"key":"q","value":"requestedFor==\"urn:ngsi-ld:Building:store001\""},{"key":"options","value":"keyValues"},{"key":"attrs","value":"orderedProduct"}]},"description":"The query below returns an array of stores in which a given product is sold.\n\nThe query  `q==requestedFor=\"urn:ngsi-ld:Building:store001\"`  is used to filter the entities.\n\nThe request returns an array of `orderedProduct` attributes in the response.\nThis is the reciprocal of the previous request."},"response":[],"_postman_id":"86955fc3-cb83-49ed-ae81-6293d6440437"},{"name":"Obtain Stock Order","id":"0387b71b-e7ff-4580-9c8e-64a8ea62e97e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":{"raw":"http://{{orion}}/ngsi-ld/v1/entities/urn:ngsi-ld:StockOrder:001?options=keyValues","protocol":"http","host":["{{orion}}"],"path":["ngsi-ld","v1","entities","urn:ngsi-ld:StockOrder:001"],"query":[{"key":"options","value":"keyValues","description":"* `keyValues` option in order to get a more compact and brief representation, including just attribute values\n* `values` option combined with a list of attribute values  `attrs`  for an ordered list of attributes only"}]},"description":"A complete stock order can be obtained by making a standard GET request to the `/ngsi-ld/v1/entities/` endpoint and adding the appropriate URN.\n\n\nThe response returns the fully expanded entity."},"response":[],"_postman_id":"0387b71b-e7ff-4580-9c8e-64a8ea62e97e"}],"event":[{"listen":"prerequest","script":{"id":"a09d943b-7f97-4412-9419-12c5bd664a5a","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"a5c1e797-bf29-407d-8790-f86fe9c1b994","type":"text/javascript","exec":[""]}}],"variable":[{"key":"orion","value":"localhost:1026"},{"key":"datamodels-context.jsonld","value":"http://context/user-context.jsonld"},{"key":"scorpio","value":"localhost:9090"},{"key":"stellio","value":"localhost:8080","type":"string"}]}