Category: Data structure · Last updated: · Permalink
The nested format is a way of including related entities into the description of an entity. For example, a description of a Person
entity might include - nested within it's properties
- associated Family
ties and Sanction
s that have been applied to them.
The nested format is returned from the /entities/
API endpoint and is used in the data exports named targets.nested.json
and topics.nested.json
.
Underlying the data model is a simple notion: everything is an entity. To represent relationships in the database, we let entities reference other entities by their ID. For example, a Passport
entity has a property called holder
that contains the entity ID of the Person
to which the document belongs.
In some cases, we want to additionally store data about a relationship. The relationship then is modelled as an entity. For example, an Ownership
entity is a link between a Company
and Person
and can contain information like a startDate
, endDate
or percentShare
. In this case, the Ownership
has two properties - asset
and owner
- that contain the entity IDs of the related entities.
The nested entity representation replaces these entity IDs with the full data of the entity they refer to. For example, if a Person
has a property addressEntity
with an ID value of addr-xxxx
, in the nested output this will be a JSON object like this (abridged):
{
"id": "individual-1"
"schema": "Person",
"properties": {
"name": "....",
"addressEntity": [
{
"id": "addr-xxxx",
"schema": "Address",
"properties": {
"full": ["New York, USA"]
}
}
]
}
}
There's an additional twist: entity relationships are interesting when they are outbound (entity A pointing at entity B), but also when they are inbound (entity B being pointed at by entity A).
For example, a Person
entity pointing at an Address
via its addressEntity
property is an outbound reference. A Passport:holder
, on the other hand, references the Person
it is held by, so the reference is owned by the Passport
, not the Person
.
In order for that relationship to be included in a nested Person
entity, we use a stub property: in this case, Person:identification
will contain an array of Passport
entities, all of which have the Person
's ID as their holder
property. Stub properties are used to assign a property name to the opposite direction viewpoint of an entity reference.
Another example: the Ownership
entity references an owner
, for example a Person
or Company
. In a nested data extract, that Person
or Company
would include a list of Ownerships
in its ownershipOwner
stub property, which is the inverse of the Ownership:owner
property.
In theory, nested entities could contain an infinite depth of nested data. However, both the API endpoint and the data exports limit the depth to one step by default: a Person
will contain a list of Address
in addressEntity
, but those Address
entities will not, in turn, nest all the things
located there ( things
is the stub property inverse of addressEntity
).
There's an exception to this, for entity types like Ownership
. They exist to connect two other entities (in the schema metadata, they are marked schema.edge
). Such edge entities will contain a further level of nesting. This way, the asset
owned by a Person
via an Ownership
is included in the nested representation of the Person
as well.
Once the nesting depth is exhausted, the data will revert to including the IDs of referenced entities instead of expanding them into entities. This allows you to manually recurse into more depth by looking up the relevant entity.
OpenSanctions is free for non-commercial users. Businesses must acquire a data license to use the dataset.