This annex is informative and is intended to show in action the JSON-LD representation defined by NGSI-LD.
JSON representations of the examples shown in this annex can be found at [i.15].
Figure C.2.1‑1 shows a diagram representing a property graph to be used for the examples discussed in this clause.
As per the algorithms described above and as per the rules for generating the JSON-LD representation of NGSI-LD entities the above graph will result in the following JSON-LD representations. The syntax has been checked using the JSON-LD Playground tool [i.5].
Normalized Representation
The normalized representation is a lossless representation of an Entity, where every Property is defined by a type and a value and every Relationship is defined by a type and an object.
Below there is a representation of an Entity of Type "Vehicle". It can be observed that the @context is composed of different parts, namely the Core @context and several vocabulary-specific @contexts.
It is noteworthy that the @context corresponding to the Parking domain is included as it is referenced through the isParked Relationship.
"tyreTreadDepths": {"type": "ListProperty","valueList": [300, 300, 120, [6],"valueType": "Integer","unitCode": "MMT"},"passengers": {"type": "Relationship","objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]
"route": {"type": "ListRelationship","objectType": "City","objectList": [{"object": "urn:ngsi-ld:City:Antwerp"},{"object": "urn:ngsi-ld:City:Rotterdam"}{"object": "urn:ngsi-ld:City:Amsterdam"}]
Normalized Representation when inline Linked Entity retrieval is used
When inline Linked Entity retrieval (see clause 4.5.23.2) is specified, any Relationships which target Entities stored locally or include an objectType Attribute are returned in an expanded format. Attributes of type "Relationship" are returned with an additional entity sub-Attribute, which holds the normalized Linked Entity data corresponding to the Relationship's target object URI. Attributes of type "ListRelationship" are returned with an additional entityList sub-Attribute which in turn holds an ordered array of the normalized Linked Entities corresponding to the target "objectList" URIs.
"tyreTreadDepths": {"type": "ListProperty","valueList": [300, 300, 120, [6],"valueType": "Integer","unitCode": "MMT"},"passengers": {"type": "Relationship","objectType": "Person",
"entity": [{
},
]},"route": {"type": "ListRelationship","objectType": "City","objectList": [{"object": "urn:ngsi-ld:City:Antwerp"},{"object": "urn:ngsi-ld:City:Rotterdam"}{"object": "urn:ngsi-ld:City:Amsterdam"}],"entityList": [{
},
]},
Normalized Representation when flattened Linked Entity retrieval is used
When flattened Linked Entity retrieval (see clause 4.5.23.3) is specified, an array of normalized Entities is returned. Whenever a Relationship Attribute targets an Entity stored locally or includes an objectType, an additional normalized Linked Entity holding data corresponding to the Relationship's target object URI is appended to the array. For Attributes of type "ListRelationship", an array of normalized Linked Entities is appended, which hold the data corresponding to each of the target URIs found within its objectList.
[
"tyreTreadDepths": {"type": "ListProperty","valueList": [300, 300, 120, [6],"valueType": "Integer""unitCode": "MMT"},"passengers": {"type": "Relationship","objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]},"route": {"type": "ListRelationship","objectType": "City","objectList": [{"object": "urn:ngsi-ld:City:Antwerp"},{"object": "urn:ngsi-ld:City:Rotterdam"}{"object": "urn:ngsi-ld:City:Amsterdam"}]},"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]
},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]
Normalized Representation when Language Filter is used
When the Language Filter (see clause 4.15) is used, Properties of type "LanguageProperty" are returned as type "Property", and their languageMaps are reduced to simple strings. For example if the language filter lang=fr is specified, only the value for French language is present.
"tyreTreadDepths": {"type": "ListProperty","valueList": [300, 300, 120, [6],"valueType": "Integer","unitCode": "MMT"},"passengers": {"type": "Relationship","objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]},"route": {"type": "ListRelationship","objectType": "City","objectList": [{"object": "urn:ngsi-ld:City:Antwerp"},{"object": "urn:ngsi-ld:City:Rotterdam"}{"object": "urn:ngsi-ld:City:Amsterdam"}]},"@context": [
Concise Representation
The concise representation is a terser, lossless form of the normalized representation, where redundant Attribute type members are omitted and the following rules are applied:
"tyreTreadDepths": {"valueList": [300, 300, 120, [6],"valueType": "Integer""unitCode": "MMT"},"passengers": {"objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]},"route": {"objectType": "City","objectList": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"]
"@context": [
Concise Representation when inline Linked Entity retrieval is used
When inline Linked Entity retrieval (see clause 4.5.23.2) is specified, any Relationships which target Entities stored locally or include an objectType Attribute are returned in an expanded format. The concise Linked Entity data corresponding to the Relationship's target object URI is returned within an entity sub-Attribute. Attributes of type "ListRelationship" are returned within an entityList sub-Attribute which in turn holds an ordered array of the Linked Entities in the concise format corresponding to each of the targetobjectList URIs.
"tyreTreadDepths": {"valueList": [300, 300, 120, [6],"valueType": "Integer","unitCode": "MMT"},"passengers": {"objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"],"entity": [{
]},"route": {"objectType": "City","objectList": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"],"entityList": [{
"name": " Antwerp"
},
"name": "Rotterdam
"name": "Amsterdam"
]},
Concise Representation when flattened Linked Entity retrieval is used
When flattened Linked Entity retrieval (see clause 4.5.23.3) is specified, an array of concise Entities is returned. Whenever a Relationship Attribute targets an Entity stored locally or includes an objectType, an additional concise Linked Entity holding data corresponding to the Relationship's target object URI is appended to the response. For Attributes of type "ListRelationship", an array of concise Linked Entities is appended to the response which hold the data corresponding to each of the target URIs found within its objectList.
[
"tyreTreadDepths": {"valueList": [300, 300, 120, [6],"valueType": "Integer",
"unitCode": "MMT"},"passengers": {"objectType": "Person","object": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]},"route": {"objectType": "City","objectList": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"]
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]
"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]
Concise representation when Language Filter is used
The rules apply as defined in the previous examples. For example if the language filter lang=fr is specified.
"tyreTreadDepths": {"valueList": [300, 300, 120, [6],"valueType": "Integer","unitCode": "MMT"},"passengers": {"objectType": "Person","objectList": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"]},"route": {"objectType": "City","objectList": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"]},
Simplified Representation
The simplified representation is a collapsed, lossy representation of an Entity, which focuses on Property Values and Relationship objects present at the first level of the graph only.
"tyreTreadDepths": [300, 300, 120, [6],"passengers": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"],"route": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"],
Simplified Representation when inline Linked Entity retrieval is used
When inline Linked Entity retrieval (see clause 4.5.23.2) is specified, any Relationships which target Entities stored locally or include an objectType Attribute are returned as a JSON object holding key-value pairs corresponding to the data from the Relationship's target object URI in simplified format. Attributes of type "ListRelationship" are returned as array of JSON objects each holding key-value pairs corresponding to the data obtained from the target objectList URIs.
"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": " OffStreetParking",
"tyreTreadDepths": [300, 300, 120, [6],"passengers": [{"id": "urn:ngsi-ld:Person:Alice","type": "Person","name": "Alice"},{"id": "urn:ngsi-ld:Person:Bob","type": "Person","name": "Bob"}],
{
Simplified Representation when flattened Linked Entity retrieval is used
When flattened Linked Entity retrieval (see clause 4.5.23.3) is specified, an array of JSON Objects is returned. Whenever a Relationship Attribute targets an Entity stored locally or includes an objectType, an additional JSON Object of key-value pairs holding data corresponding to the Relationship's target object URI is appended to the response. For Attributes of type "ListRelationship", an array of JSON Objects each holding key-value pairs corresponding to the data obtained from the target objectList URIs is appended to the response.
[
{"id": "urn:ngsi-ld:Vehicle:A4567","type": "Vehicle","brandName": "Mercedes","street": {"languageMap": {"fr": "Grand Place","nl": "Grote Markt"}}"isParked": "urn:ngsi-ld:OffStreetParking:Downtown1","category": {"vocab": "non-commercial"},"tyreTreadDepths": [300, 300, 120, [6],"passengers": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"],"route": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"],"@context": ["http://example.org/ngsi-ld/latest/commonTerms.jsonld","http://example.org/ngsi-ld/latest/vehicle.jsonld","http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": " OffStreetParking",
},{"id": "urn:ngsi-ld:Person:Alice","type": "Person","name": "Alice"}{"id": "urn:ngsi-ld:Person:Bob","type": "Person","name": "Bob"},{
},
Simplified Representation of Natural Language Attributes
The simplified natural language representation is a collapsed representation of an Entity, which focuses on Property Values and Relationship objects present at the first level of the graph, and where languageMaps are reduced to simple string properties. For example if the language filter lang=fr is specified.
"tyreTreadDepths": [300, 300, 120, [6],"passengers": ["urn:ngsi-ld:Person:Alice", "urn:ngsi-ld:Person:Bob"],"route": ["urn:ngsi-ld:City:Antwerp","urn:ngsi-ld:City:Rotterdam","urn:ngsi-ld:City:Amsterdam"],
Multiple attribute example
Below is an example, where the speed of the car is provided by two different sources. As both may be relevant at the same time, there are two individual attribute instances for speed; each is identified by a datasetId and both instances are represented in an array. The datasetId enables individually creating, updating and deleting a particular instance without affecting the instance from another source.
Simplified Representation of a multi-attribute
The simplified representation is a collapsed, lossy representation of an Entity, which focuses on Property Values and Relationship objects present at the first level of the graph only.
Normalized Representation
The normalized representation is a lossless representation of an Entity, where every Property is defined by a type and a value and every Relationship is defined by a type and an object.
Below there is a representation of an Entity of Type "OffStreetParking". It can be observed that the @context is composed of two different elements, the Core one and the vocabulary-specific one.
Concise Representation
The concise representation is a terser, lossless form of the normalized representation, where redundant Attribute type members are omitted and the following rules are applied:
Simplified representation
The Simplified Representation (also known as "keyValues") is a lossy, collapsed representation of an Entity, which focuses on Property Values and Relationship objects present at the first level of the graph only.
Normalized GeoJSON Representation
The normalized GeoJSON representation of a single Entity is defined as a single GeoJSON Feature object as follows:
The GeoJSON representation of multiple Entities is defined as a GeoJSON FeatureCollection object containing an array of GeoJSON features corresponding to the individual Entity representations.
Concise GeoJSON Representation
The concise GeoJSON representation of a single Entity is defined as a single GeoJSON Feature object as follows:
The concise GeoJSON representation of multiple Entities is defined as a GeoJSON FeatureCollection object containing an array of GeoJSON features corresponding to the individual Entity representations in concise GeoJSON format.
Simplified GeoJSON Representation
The simplified GeoJSON representation of a single Entity is defined as a single GeoJSON Feature object where the properties represent a collapsed representation of the Entity, which focuses on Property Values and Relationship objects present at the first level of the graph.
The simplified GeoJSON representation of multiple Entities is defined as a GeoJSON FeatureCollection object containing an array of GeoJSON features corresponding to the individual Entity representations in simplified GeoJSON format.
The disposition of the @context can be as an inline JSON object, as a dereferenceable URI or as a (multiple) combination of both. In the examples above the @context is provided through several dereferenceable URIs. The resulting @context (obtained by merging the content of the resource referenced by the referred URIs) is shown below.
Below there is an example representation of a Context Source Registration. It makes use of the @context formerly described.
The Registration is referring to a Temporal Context Source capable of providing temporal information from Entities of type "Vehicle" and "OffStreetParking", meeting certain id requirements. More concretely, it can only provide the referenced Properties and Relationships. Temporal information is provided for the given managementInterval, i.e. related to createdAt and modifiedAt Temporal Properties. The managementInterval is specified as an open interval, so only a starting point is given. In addition, the Registration example covers a particular geographical area.
Below there is an example of a Context Subscription. It makes use of the @context formerly described.
The subject of the Context Subscription is Entities of Type Vehicle which speed is greater than 50, and located close to a certain area defined by a reference spatial point. Every time the speed (watched Attribute) of a concerned vehicle, changes, a new notification (including the new speed value) will be received in the specified endpoint.
This clause introduces some simple usage examples of the NGSI-LD API (HTTP REST binding). They are not intended to be exhaustive but just a sample for helping readers to understand better the present document. ETSI ISG CIM published a Developer's Primer with many more examples, see ETSI GR CIM 008 [i.21].
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","brandName": "Volvo","@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","brandName": "Volvo","@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{"id": "urn:ngsi-ld:Vehicle:A456","type": "Vehicle","brandName": "Mercedes","@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","speed": [{"type": "Property","value": 120,"observedAt": "2018-08-01T12:03:00Z"},{"type": "Property","value": 80,"observedAt": "2018-08-01T12:05:00Z"},{"type": "Property","value": 100,"observedAt": "2018-08-01T12:07:00Z"}],"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","speed": [{"type": "Property","value": 120,"observedAt": "2018-08-01T12:03:00Z"},{"type": "Property","value": 80,"observedAt": "2018-08-01T12:05:00Z"},{"type": "Property","value": 100,"observedAt": "2018-08-01T12:07:00Z"}],"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","speed": {"type": "Property","values": [[120,"2018-08-01T12:03:00Z"],[80,"2018-08-01T12:05:00Z"],[100,"2018-08-01T12:07:00Z"]]},"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
{"id": "urn:ngsi-ld:EntityTypeList:34534657","type": "EntityTypeList","typeList": ["Vehicle","OffStreetParking","http://example.org/parking/ParkingSpot"]}
[{"id": "http://example.org/vehicle/Vehicle","type": "EntityType","typeName": "Vehicle","attributeNames": ["brandName","isParked","location","speed"]},{"id": "http://example.org/parking/OffStreetParking","type": "EntityType","typeName": "OffStreetParking","attributeNames": ["availableSpotNumber","isNextToBuilding","location","totalSpotNumber"]},{"id": "http://example.org/parking/ParkingSpot","type": "EntityType","typeName": "http://example.org/parking/ParkingSpot","attributeNames":["location","http://example.org/parking/status"]}]
{"id": "http://example.org/vehicle/Vehicle","type": "EntityTypeInfo","typeName": "Vehicle","entityCount": 2,"attributeDetails": [{"id": "http://example.org/vehicle/brandName","type": "Attribute","attributeName": "brandName","attributeTypes": ["Property"]},{"id": "http://example.org/vehicle/isParked","type": "Attribute","attributeName": "isParked","attributeTypes": ["Relationship"]},{"id": "https://uri.etsi.org/ngsi-ld/location","type": "Attribute","attributeName": "location","attributeTypes": ["GeoProperty"]},{"id": "http://example.org/vehicle/speed","type": "Attribute","attributeName": "speed","attributeTypes": ["Property"]}]}
{"id": "urn:ngsi-ld:AttributeList:56534657","type": "AttributeList","attributeList": ["brandName","isParked","location","speed","http://example.org/parking/status"]}
[{"id": "http://example.org/vehicle/brandName","type": "Attribute","attributeName": "brandName","typeNames": ["Vehicle"]},{"id": "http://example.org/vehicle/isParked","type": "Attribute","attributeName": "isParked","typeNames": ["Vehicle"]},{"id": "https://uri.etsi.org/ngsi-ld/location","type": "Attribute","attributeName": "location","typeNames": ["Vehicle","OffStreetParking","http://example.org/parking/ParkingSpot"]},{"id": "http://example.org/vehicle/speed","type": "Attribute","attributeName": "speed","typeNames": ["Vehicle"]},{"id": "http://example.org/parking/status","type": "Attribute","attributeName": "http://example.org/parking/status","typeNames": ["http://example.org/parking/ParkingSpot"]}]
{"id": "http://example.org/vehicle/brandName","type": "Attribute","attributeName": "brandName","attributeTypes": ["Property"],"typeNames": ["Vehicle"],"attributeCount": 2}
[{"id": "urn:ngsi-ld:Vehicle:A4567","type": "Vehicle","marque": "Opel Karl","@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","speed": {"type": "Property","max": [[120,"2018-08-01T12:00:00Z","2018-08-01T12:04:00Z"],[100,"2018-08-01T12:04:00Z","2018-08-01T12:08:00Z"]],"avg": [[120,"2018-08-01T12:00:00Z","2018-08-01T12:04:00Z"],[90,"2018-08-01T12:04:00Z","2018-08-01T12:08:00Z"]]},"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": "OffStreetParking","scope": "/Madrid/Centro","name": {"type": "Property","value": "Downtown One"},"availableSpotNumber": {"type": "Property","value": 121,"observedAt": "2017-07-29T12:05:02Z","reliability": {"type": "Property","value": 0.7},"providedBy": {"type": "Relationship","object": "urn:ngsi-ld:Camera:C1"}},"totalSpotNumber": {"type": "Property","value": 200},"location": {"type": "GeoProperty","value": {"type": "Point","coordinates": [-8.5,41.2]}},"@context": ["http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{"id": "urn:ngsi-ld:OffStreetParking:Corte4","type": "OffStreetParking","scope": ["/Madrid/Cortes","/Company894/UnitC"],"name": {"type": "Property","value": "Corte4"},"availableSpotNumber": {"type": "Property","value": 121,"observedAt": "2017-07-29T12:05:02Z","reliability": {"type": "Property","value": 0.7},"providedBy": {"type": "Relationship","object": "urn:ngsi-ld:Camera:C1"}},"totalSpotNumber": {"type": "Property","value": 100},"location": {"type": "GeoProperty","value": {"type": "Point","coordinates": [-8.6,41.3]}},"@context": ["http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
[{"id": "urn:ngsi-ld:Vehicle:B9211","type": "Vehicle","scope": {"type": "Property","values": [["/Madrid/Centro","2018-08-01T11:00:00Z"]]},"speed": {"type": "Property","values": [[30,"2018-08-01T12:03:00Z"],[60,"2018-08-01T12:05:00Z"],[50,"2018-08-01T12:07:00Z"]]},"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]},{"id": "urn:ngsi-ld:Vehicle:A8311","type": "Vehicle","scope": {"type": "Property","values": [[["/Madrid/Centro","/Company123/UnitA"],"2018-08-01T12:10:00Z"]]},"speed": {"type": "Property","values": [[40,"2018-08-01T12:12:00Z"],[60,"2018-08-01T12:14:00Z"],[50,"2018-08-01T12:16:00Z"]]},"@context": ["http://example.org/ngsi-ld/latest/vehicle.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}]
Vehicle B9211 has already been within the Scope /Madrid/Centro before the beginning of the request interval, whereas Vehicle A8311 only entered the Scope within the request interval. Thus in the latter case only Property values are included that have been observed after the Scope has become valid.
In NGSI-LD, a TemporalProperty is represented only by its value, i.e. no sub-Properties of TemporalProperty nor sub-Relationships of TemporalProperty can be conveyed. In more formal language, a TemporalProperty does not allow reification. The term TemporalProperty has been reserved for non-reified structural timestamps (observedAt, createdAt, modifiedAt, deletedAt), which capture the temporal evolution of Attributes. Only such structural timestamps can be used as timeproperty in Temporal Queries as mandated by clause 4.11.
The following examples show how time values (Date, Time, or DateTime) can be represented in NGSI-LD as reified Properties. For a reified Property whose value is assigned the JSON type Date, DateTime or Time, one mechanism is to use the Property's valueType to hold the datatype ("Date", "Datetime" or "Time"), as shown below:
Alternatively the data can be a structured to use the JSON-LD @value syntax structure, as shown below:
A third alternative to achieve the same result would be to use JSON-LD "type coercion". With type coercion, values with a special data type are defined with @type in the @context. This enforces the correct type for any occurrence. Such an @context fragment is shown below:
The above does not work, when using the @context to perform compaction, in the normalized and compact representation of NGSI-LD, due to reification of the Property, because in this case testedAt is a complex JSON object, which cannot be compacted to a DateTime type as the @context specifies. Thus, the full URI http://example.org/test/testedAt is kept, instead of the short name testedAt. In summary, user @contexts used for the normalized and compact NGSI-LD representation cannot use the JSON-LD type coercion feature.
However, in the simplified (keyValue) representation case, such an @context with the specification of testedAt could be used, as there is no reification.
As a side note, when using the above @value + @type approach, since type is mapped to @type in the NGSI-LD core @context, JSON-LD compaction will result in the following compacted value, instead of the one shown above, because @type is compacted to type:
When expanding or compacting JSON-LD terms, the JSON-LD @context to be used is always the one provided in the current API request. For the benefit of users and implementers the following examples illustrate this concept.
The scenario starts with the creation of an Entity using a JSON-LD @context as follows:
{"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": "OffStreetParking","name": {"type": "Property","value": "Downtown One"},"availableSpotNumber": {"type": "Property","value": 121,"observedAt": "2017-07-29T12:05:02Z"},"totalSpotNumber": {"type": "Property","value": 200},"@context": ["http://example.org/ngsi-ld/latest/parking.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}
The content of the @context utilized for the referred Entity creation (at http://example.org/ngsi-ld/latest/parking.jsonld) is as follows:
"OffStreetParking": "http://example.org/parking/OffStreetParking","availableSpotNumber": "http://example.org/parking/availableSpotNumber","totalSpotNumber": "http://example.org/parking/totalSpotNumber","name": "http://example.org/parking/name"
At Entity creation time the implementation will perform the expansion of terms using the JSON-LD @context depicted above.
Now it is needed to retrieve our initial Entity. For retrieving such Entity, this time, a different JSON-LD @context is going to be utilized, as follows:
"OffP": "http://example.org/parking/OffStreetParking","ava": "http://example.org/parking/availableSpotNumber","total": "http://example.org/parking/totalSpotNumber"
This new @context, even though it makes use of the same set of Fully Qualified Names, is defining new short strings as terms. The reasons for that could be multiple: to facilitate data consumption by clients, to save some bandwidth, to enable a more (or less) human-readable response payload body in a language different than English, etc.
In this particular case, the result of the Entity retrieval will be as depicted below. It can be observed that the terms defined by the JSON-LD @context provided at retrieval time are used to render the Entity content (compaction), and not the terms that were provided at creation time (which may be no longer known by the broker).
It is also interesting to note that the @context array of the response payload body contains, indeed, our header-supplied @context:
{"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": "OffP","name": {"type": "Property","value": "Downtown One"},"ava": {"type": "Property","value": 121,"observedAt": "2017-07-29T12:05:02Z"},"total": {"type": "Property","value": 200},"@context": ["http://example.org/ngsi-ld/latest/parking-abbreviated.jsonld","https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"]}
{"id": "urn:ngsi-ld:OffStreetParking:Downtown1","type": "http://example.org/parking/OffStreetParking","http://example.org/parking/name": {"type": "Property","value": "Downtown One"},"http://example.org/parking/availableSpotNumber": {"type": "Property","value": 121,"observedAt": "2017-07-29T12:05:02Z"},"http://example.org/parking/totalSpotNumber": {"type": "Property","value": 200},"@context": "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.9.jsonld"}
In this particular case it can be observed that the user names (Entity Type, Attributes) in the response payload body have not been compacted, and as a result the Fully Qualified Names are included. However, the core API terms have been compacted, as the Core @context is always considered to be implicitly present if not specified explicitly (and that is why it is included in the JSON-LD response, as mandated by the specification).
The JSON-LD Specification [2] states clearly that only one HTTP Link header with the link relationship <http://www.w3.org/ns/json-ld#context> is required to appear. Such statement has implications in terms of providing the JSON-LD @context when using the NGSI-LD API. The main implication is that if the @context is a compound one, i.e. an @context which references multiple individual @context, served by resources behind different URIs, then a wrapper @context has to be created and hosted. The final aim is that only one @context is referenced from the JSON-LD Link header. This can be illustrated with an example:
Imagine that it is desired to create an Entity providing @context terms which are defined in two different JSON-LD @context resources:
If a developer wants to reference these two @context resources from a Link header, a wrapper @context can be easily created as follows:
As such wrapper @context needs to be referenced from a Link header by using a URI, then it will have to be hosted at some place on the Web. Usually, developers will host @context using popular and simple solutions such as GitHub or GitLab pages. As a result, developers will be able to use @context in queries or when using "application/json" as main content type managed by their applications.
It is a good practice to include the Core @context in the wrapper @context so it can be used, off-the-shelf, by external JSON-LD processing tools. However, it should be noted this is not necessary for NGSI-LD, as the Core @context is always implicitly included.
Then, using such wrapper @context, (in our example hosted at https://hosting.example.com/ngsi-ld/v1/wrapper-context.jsonld), the developer will be able to issue requests like:
Observe that in this case the broker is responding with the same wrapper @context in the Link header of the HTTP Response or within the JSON-LD response payload body (when MIME type accepted is "application/ld+json"). However, that could not be always the case, as there could be situations where the broker could need to provide a wrapper @context hosted by itself, for instance, when there are inline @context terms or when the Core @context has not been previously included by the wrapper @context (not recommended) provided within developer's requests.
JSON-LD Specification [2] says that "If a term is redefined within a context, all previous rules associated with the previous definition are removed". In addition, it is stated that "Multiple contexts may be combined using an array, which is processed in order".
In contrast to the JSON-LD Specification, the NGSI-LD specification states that the Core @context is protected and has to remain immutable. This essentially means that the Core @context has final precedence and, therefore, is always to be processed as the last one in the @context array. For clarity, data providers should place the Core @context in the final position. From the point of view of Data providers, care has to be taken so that there are no unexpected or undesired term expansions. See the following example:
The problem of the example above is that the term "location" is defined in both the Core @context and the schema.org user @context and the Core @context takes precedence for the expansion. In these situations, if one wanted to refer to the schema.org "location", the solution is to prefix the conflicting terms, so that there cannot be any clashing. Therefore, if the intent is to refer to https://schema.org/location throughout, the example above can be modified as shown below:
Note that the Core @context should be placed in the last position of the @context array. NGSI-LD implementations are required to render content following this approach, which has been undertaken in order to maximize compatibility with JSON-LD processing tools. This example works because the "schema:" prefix has already been defined by the schema.org @context.
Using JSON-LD [2] syntax, typed values can be expressed using the JSON-LD @type keyword when defining a term, where @type value holds a URI which indicates the value's datatype. However, it can be desirable for a Context Broker to be able to hold simpler untyped values within a Property's value attribute and separately use a Property's valueType to hold the value's datatype. This format can be used to accommodate multiple acceptable datatype formats for the data to be held within a single Property and still hold sufficient meta data to be able to distinguish between them.
For example, consider an ontology for an Entity of type "Place" which has an address Property, where the address Property can either be an unstructured address in the form of a "String" or a structured "PostalAddress" JSON Object with street, city and country attributes - the following JSON-LD schema can be defined:
Example JSON-LD schema
Then the following two Entities of type "Place" can be created using the address.valueType Property to distinguish between the two formats:
As specified in [35], the atomic piece of information that creators can digitally sign in an NGSI-LD ecosystem is each single Attribute of an Entity. In the following example, an Entity of type "Store" with two Properties, "address" and "location" is presented. The "address" Property is digitally signed. The signature is created using one Ed25519 instantiation of the Edwards-Curve Digital Signature Algorithm (EdDSA).The used crypto suite is "eddsa-rdfc-2022".