Knowledge Base

Viewing schema data with APOC Procedures

APOC Procedures offers meta procedures to view information about your database schema and the data it stores.

The procedure apoc.meta.schema() uses a sampling of the graph data to produce a map of metadata on the graph labels, relationships, properties, and more.

As the metadata returned is a map, it can be transformed to better surface desired information, and may be formatted to provide a more tabular structure of the data.

This requires UNWINDing the collection of map keys and obtaining the value for each key.

Here’s one possible way to transform the schema data so it resembles the USER_TAB_COLUMNS system object from Oracle:

CALL apoc.meta.schema() YIELD value as schemaMap
UNWIND keys(schemaMap) as label
WITH label, schemaMap[label] as data
WHERE data.type = "node"
UNWIND keys(data.properties) as property
WITH label, property, data.properties[property] as propData
RETURN label,
property,
propData.type as type,
propData.indexed as isIndexed,
propData.unique as uniqueConstraint,
propData.existence as existenceConstraint

Here’s an example result table, if run on the movies graph from the built-in tutorial using :play movies, and adding an index on :Person(name) and a unique constraint on :Movie(title). Order of the output is not guaranteed to be the same across Neo4j instances, though the labels should always be grouped together.

label property type isIndexed uniqueConstraint existenceConstraint

"Person"

"name"

"STRING"

true

false

false

"Person"

"born"

"STRING"

false

false

false

"Movie"

"tagline"

"STRING"

false

false

false

"Movie"

"title"

"STRING"

true

true

false

"Movie"

"released"

"INTEGER"

false

false

false

As an alternative, if using APOC 3.1.3.8 or newer (along the 3.1.x line) or 3.2.0.4 or newer (along the 3.2.x line) you can use apoc.map.sortedProperties(), using UNWIND on the result.

CALL apoc.meta.schema() yield value
UNWIND apoc.map.sortedProperties(value) as labelData
WITH labelData[0] as label, labelData[1] as data
WHERE data.type = "node"
UNWIND apoc.map.sortedProperties(data.properties) as property
WITH label, property[0] as property, property[1] as propData
RETURN label,
property,
propData.type as type,
propData.indexed as isIndexed,
propData.unique as uniqueConstraint,
propData.existence as existenceConstraint

Output will be the same but alphabetically sorted by label, then property.

label property type isIndexed uniqueConstraint existenceConstraint

"Movie"

"released"

"INTEGER"

false

false

false

"Movie"

"tagline"

"STRING"

false

false

false

"Movie"

"title"

"STRING"

true

true

false

"Person"

"born"

"STRING"

false

false

false

"Person"

"name"

"STRING"

true

false

false

Keep in mind that since Neo4j allows dynamic node properties instead of a fixed schema, a sampling of the database is needed to obtain this data. It is possible this may miss some elements in the graph, such as node properties that are only present in a small subset of nodes within a label.