## 21.1. Schema Index Procedures

This section describes procedures that can be used to create and query schema indexes.

`apoc.schema.assert({indexLabel:[indexKeys],…​},{constraintLabel:[constraintKeys],…​}, dropExisting : true) yield label, key, unique, action` | drops all other existing indexes and constraints when `dropExisting` is `true` (default is `true`), and asserts that at the end of the operation the given indexes and unique constraints are there, each label:key pair is considered one constraint/label.
`apoc.schema.nodes([config]) yield name, label, properties, status, type` | get all indexes and constraints information for all the node labels in your database, in optional config param could be define a set of labels to include or exclude
`apoc.schema.relationships([config]) yield name, type, properties, status` | return all the constraint information for all the relationship types in your database, in optional config param could be define a set of types to include or exclude
`apoc.schema.node.constraintExists(labelName, properties)` | return the constraints existence on node
`apoc.schema.relationship.constraintExists(type, properties)` | return the constraints existence on relationship

### 21.1.1. Schema Information

This section describes procedures that can be used to query and create schema indexes.

To drop or create index or constraint, you can use the following procedure:

    CALL apoc.schema.assert({indexLabel:[[indexKeys]], ...}, {constraintLabel:[constraintKeys], ...}, dropExisting : true)
    YIELD label, key, keys, unique, action

Where the outputs are:

- label
- key
- keys, list of the key
- unique, if the index or constraint are unique
- action, can be the following values: DROPPED, CREATED

To retrieve indexes and constraints information for all the node labels in your database, you can use the following procedure:

    CALL apoc.schema.nodes()
    YIELD name, label, properties, status, type

Where the outputs are:

- name of the index/constraint,
- label
- properties, (for Neo4j 3.1 and lower versions is a single element array) that are affected by the constraint
- status, for index can be one of the following values: ONLINE, POPULATING and FAILED
- type, always "INDEX" for indexes, constraint type for constraints
- failure, the failure description of a failed index
- populationProgress, the population progress of the index in percentage
- size, the size of the index
- valuesSelectivity, computes the selectivity of the unique values
- userDescription, a user friendly description of what this index indexes

To retrieve the constraint information for all the relationship types in your database, you can use the following procedure:

    CALL apoc.schema.relationships()
    YIELD name, type, properties, status

Where the outputs are:

- name of the constraint
- type of the relationship
- properties, (for Neo4j 3.1 and lower versions is a single element array) that are affected by the constraint
- status

Config optional param is a map and its possible values are:

- labels : list of labels to retrieve index/constraint information
- excludeLabels: list of labels to exclude from retrieve index/constraint information
- relationships: list of relationships type to retrieve constraint information
- excludeRelationships: list of relationships' type to exclude from retrieve constraint information

Exclude has more power than include, so if excludeLabels and labels are both valued, procedure considers excludeLabels only, the same for relationships.

    CALL apoc.schema.nodes({labels:['Book']})
    YIELD name, label, properties, status, type

N.B. Constraints for property existence on nodes and relationships are available only for the Enterprise Edition.

To retrieve the index existence on node, you can use the following user function:

    RETURN apoc.schema.node.indexExists(labelName, propertyNames)

The output return the index existence on node is present or not

To retrieve if the constraint exists on node, you can use the following user function:

    RETURN apoc.schema.node.constraintExists(labelName, propertyNames)

The output return the constraint existence on node.

To retrieve if the constraint exists on relationship, you can use the following user function:

    RETURN apoc.schema.relationship.constraintExists(type, propertyNames)

The output return the constraint on the relationship is present or not

#### 21.1.1.1. Examples

##### List Schema assert

When you:

    CALL apoc.schema.assert({Foo:['bar']},null)

you will receive this result:

When you:

    CALL apoc.schema.assert(null,{Foo:['bar']})

you will receive this result:

When you:

    CALL apoc.schema.assert(null,null)

you will receive this result:

##### List indexes and constraints for nodes

Given the following cypher statements:

    CREATE CONSTRAINT ON (bar:Bar) ASSERT exists(bar.foobar)
    CREATE CONSTRAINT ON (bar:Bar) ASSERT bar.foo IS UNIQUE
    CREATE INDEX ON :Person(name)
    CREATE INDEX ON :Publication(name)
    CREATE INDEX ON :Source(name)

When you

    CALL apoc.schema.nodes()

you will receive this result:

##### List constraints for relationships

Given the following cypher statements:

    CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
    CREATE CONSTRAINT ON ()-[starred:STARRED]-() ASSERT exists(starred.month)

When you

    CALL apoc.schema.relationships()

you will receive this result:

##### Check if an index or a constraint exists for a Label and property

Given the previous index definitions, running this statement:

    RETURN apoc.schema.node.indexExists("Publication", ["name"])

produces the following output:

Given the previous constraint definitions, running this statement:

    RETURN apoc.schema.node.constraintExists("Bar", ["foobar"])

produces the following output:

If you want to check if a constraint exists for a relationship you can run this statement:

    RETURN apoc.schema.relationship.constraintExists('LIKED', ['day'])

and you get the following result: