Skip to main content

Entity maps

An entity map remembers who answered a query. Run a query once, and the broker records which entities matched and which context sources each one came from, as a resource with its own identifier. A later request that carries the map's identifier is answered inside that membership, and the map is echoed back so you can tell what you were talking to.

The idea is the query-side sibling of a snapshot. Where a snapshot freezes the data, an entity map freezes the membership. The specification defines both, and clause 5.14 gives the EntityMap its own resource, representation and operations.

Creating a map from a query​

Send the query to GET /ngsi-ld/v1/entityMaps instead of GET /ngsi-ld/v1/entities. The answer carries the matched entities, and it is also the new map.

GET /ngsi-ld/v1/entityMaps?type=Vehicle
Accept: application/json
HTTP/1.1 201 Created
Content-Type: application/json
Location: /ngsi-ld/v1/entityMaps/urn:ngsi-ld:EntityMap:1
NGSILD-EntityMap: urn:ngsi-ld:EntityMap:1

{
"id": "urn:ngsi-ld:EntityMap:1",
"type": "EntityMap",
"expiresAt": "2026-10-26T11:00:00.000Z",
"entityMap": {
"urn:ngsi-ld:Vehicle:1": [
"@none"
]
},
"linkedMaps": {}
}

The entityMap member maps every matched entity to the context sources it came from, and ["@none"] marks an entity answered from the broker's own store. A query forwarded to registered sources records the source names instead. The NGSILD-EntityMap header and the Location header name the new resource, whose default lifetime the answer's expiresAt shows.

The ordinary query endpoint creates a map too. Adding entityMap=true to GET /ngsi-ld/v1/entities answers the entities as usual and adds the NGSILD-EntityMap header, so a client that wants the map keeps it and one that does not ignores it. A plain query without the option creates nothing.

Reading and keeping a map​

GET /ngsi-ld/v1/entityMaps/urn:ngsi-ld:EntityMap:1 returns the map as shown above. PATCH sets a new expiresAt to keep it alive, and DELETE removes it, answering 204. A repeat delete answers 404, as does an unknown identifier from the start. An output-only member in a patch, such as the entityMap membership itself, is ignored.

Working under a map​

Carry the identifier in an NGSILD-EntityMap header on a later request. The temporal API keeps the follow-up inside the map's membership, and echoes the header on the answer.

GET /ngsi-ld/v1/temporal/entities/urn:ngsi-ld:Vehicle:1
NGSILD-EntityMap: urn:ngsi-ld:EntityMap:1
HTTP/1.1 200 OK
Content-Type: application/json
NGSILD-EntityMap: urn:ngsi-ld:EntityMap:1

An entity created after the map was made is not pulled in by a follow-up. The membership is fixed at creation, which is the point. A temporal query creates a map of its own the same way, with entityMap=true on the temporal query or by sending the temporal query to the entity-maps resource.

What gets refused​

  • 400 BadRequestData for a map creation with no narrowing member, such as an identifier alone, or a query narrowed only by a pick.
  • 400 BadRequestData for URL parameters on a map creation whose query arrived in a POST body.
  • 400 InvalidRequest for entityMapLifetime without entityMap=true.
  • 400 BadRequestData for an expiresAt in the past, or one with more than six fractional digits.