Skip to the content.

Neo4j Versioner Core Documentation

Neo4j Versioner Core is a collection of procedures, aimed to help developers to manage the Entity-State model, by creating, updating and querying the graph.

License

Apache License 2.0

Installation

  1. Download the latest release;
  2. Put the downloaded jar file into $NEO4J_HOME/plugins folder;
  3. Start/Restart Neo4j.

Version Compatibility Matrix

Versioner version Neo4j version
2.x.x 3.5.x
4.2.x 4.2.x

About

Neo4j Versioner Core has been developed by Alberto D’Este and Marco Falcier.

Entity-State (ES) Data Model

The current data model uses two kind of nodes: the Entity nodes, created by the user through a given Label and the State nodes, managed by the Graph Versioner. The State node can be seen as the set of mutable properties which regards the Entity, which possesses only immutable properties. There are 4 different relationships:

This is how the data model looks like:

ES Data Model

Entity-State-R (ESR) Data Model

From version 2.0.0 you can now also version relationships: when an Entity node is created, also its own R node is created. So from the previous model, you can also add this new relationship:

The R node is the Entity’s access point for its own incoming relationships; this way, we can also keep track of relationships verse. Remember, only relationships managed with this tool will be versioned.

This is how the data model looks like:

ESR Data Model

Procedures Reference

Neo4j procedure documentation can also be found using CALL dbms.procedures().

How to call Core Versioner Procedures on your procedures/functions

If you want to use Neo4j Versioner Core procedures on your procedures/functions you simply create a new instance:

Optional<Init> result = new InitBuilder().withTransaction(transaction).withLog(log).build();
result.ifPresent(a -> a.init("EntityLabel", entityProps, stateProps, additionalLabel, date));

Maven users

Add the following repository and dependency to your pom.xml file

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.h-omer</groupId>
    <artifactId>neo4j-versioner-core</artifactId>
    <version>4.2.4</version>
    <scope>provided</scope>
</dependency>

Gradle users

Add the following repository and dependency to your build.gradle file

repositories {
    maven { url 'https://jitpack.io' }
}
dependencies {
    compile 'com.github.h-omer:neo4j-versioner-core:4.2.4'
}

Neo4j Versioner Core must be a provided dependency on your project and it must be installed on your neo4j instance.

Procedure CheatSheet

Here you can find a “compressed” list of all the procedures:

Legend

name parameters return values description
graph.versioner.init entityLabel, {key:value,…}, {key:value,…}, additionalLabel, date node Create an Entity node with it’s R node and an optional initial State.
graph.versioner.update entity, {key:value,…}, additionalLabel, date node Add a new State to the given Entity.
graph.versioner.patch entity, {key:value,…}, additionalLabel, date node Add a new State to the given Entity, starting from the previous one. It will update all the properties, not labels.
graph.versioner.patch.from entity, state, useCurrentRel, date node Add a new State to the given Entity, starting from the given one. It will update all the properties, not labels.
graph.versioner.get.current.path entity path Get a the current path (Entity, State and rels) for the given Entity.
graph.versioner.get.current.state entity node Get the current State node for the given Entity.
graph.versioner.get.all entity path Get an Entity State path for the given Entity.
graph.versioner.get.by.label entity, label node Get State nodes with the given label, by the given Entity node.
graph.versioner.get.by.date entity, date node Get State node by the given Entity node, created at the given date.
graph.versioner.get.nth.state entity, nth node Get the nth State node for the given Entity.
graph.versioner.rollback entity, date node Rollback the current State to the first available one.
graph.versioner.rollback.to entity, state, date node Rollback the current State to the given one.
graph.versioner.rollback.nth entity, nth, date node Rollback the given Entity to the nth previous State.
graph.versioner.diff stateFrom, stateTo operation, label, oldValue, newValue Get a list of differences that must be applied to stateFrom in order to convert it into stateTo.
graph.versioner.diff.from.previous state operation, label, oldValue, newValue Get a list of differences that must be applied to the previous status of the given one in order to become the given state.
graph.versioner.diff.from.current state operation, label, oldValue, newValue Get a list of differences that must be applied to the given state in order to become the current entity state.
graph.versioner.relationship.create entitySource, entityDestination, relationshipType, {key:value,…}, date relationship Creates a new state for the source entity connected to the R node of the destination with a relationship of the given type.
graph.versioner.relationship.delete entitySource, entityDestination, relationshipType, date result Creates a new state for the source entity without a custom relationship of the given type.
graph.versioner.relationships.createTo entitySource, entityDestinations, relationshipType, {key:value,…}, date relationship Creates a new state for the source entity connected to each of the R nodes of the destinations with a relationship of the given type.
graph.versioner.relationships.createFrom entitySources, entityDestination, relationshipType, {key:value,…}, date relationship Creates a new state for each of the source entities connected to the R nodes of the destination with a relationship of the given type.
graph.versioner.relationships.delete entitySource, entityDestinations, relationshipType, date result Creates a new state for the source entity without a custom relationships for each of the destination nodes of the given type.

init

This procedure is used in order to initialize an Entity node, with an initial State. If a Map of State properties is given, a State node will be created, with both HAS_STATE and CURRENT relationships; otherwise, a State node without properties will be created. If date is given, date and startDate will be initialized with that value.

Details

Name

graph.versioner.init

Parameters

name necessity detail
entityLabel mandatory The name of the entity Label.
{key:value,...} optional A Map representing the Entity immutable properties.
{key:value,...} optional A Map representing the State properties.
additionalLabel optional The name of an additional Label to the new State.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node Node

Example call

CALL graph.versioner.init('Person', {ssn: localdatetime('1988-10-27T02:46:40'), name: 'Marco'}, {address: 'Via Roma 11'}) YIELD node RETURN node

update

This procedure is used in order to update a status of an existing Entity node. It will create a new State node, deleting the previous CURRENT relationship, creating a new one to the new created node with the current date (or the optional one, if given); then it update the last HAS_STATE relationship adding the current/given date as the endDate and creating a new HAS_STATE relationship with startDate as the current/given date. It will also create a new relationship between the new and the last State called PREVIOUS, with the old date as a property. If the Entity node has no State, it will create a new State node, with both HAS_STATE and CURRENT relationships. If no properties are passed, a new State node will be created, without properties. If a custom relationship exists between the current State and a R node, that relationship is kept on the updated State.

Details

Name

graph.versioner.update

Parameters

name necessity detail
entity mandatory The entity node to operate with.
{key:value,...} mandatory A Map representing the State properties.
additionalLabel optional The name of an additional Label to the new State.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node Node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.update(d, {context:'some details'}, 'Error', localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

patch

This procedure is used in order to patch the current status of an existing Entity node, updating/creating the given properties, maintaining the oldest and untouched one. It will create a new State node, deleting the previous CURRENT relationship, creating a new one to the new created node with the current date (or the optional one, if given); then it update the last HAS_STATE relationship adding the current/given date as the endDate and creating a new HAS_STATE relationship with startDate as the current/given date. It will also create a new relationship between the new and the last State called PREVIOUS, with the old date as a property. If the Entity node has no State, it will create a new State node, with both HAS_STATE and CURRENT relationships. If no properties are passed, a copy of the CURRENT node will be created as the new State. If a custom relationship exists between the current State and a R node, that relationship is kept on the updated State.

Details

Name

graph.versioner.patch

Parameters

name necessity detail
entity mandatory The entity node to operate with.
{key:value,...} mandatory A Map representing the State properties.
additionalLabel optional The name of an additional Label to the new State.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node Node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.patch(d, {warnings: 'some warnings'}, 'Warning', localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

patch from

This procedure is used in order to patch the current State of an existing Entity node, updating/creating the properties using the those one the given State, maintaining the oldest and untouched one. It will create a new State node, deleting the previous CURRENT relationship, creating a new one to the new created node with the current date (or the optional one, if given); then it update the last HAS_STATE relationship adding the current/given date as the endDate and creating a new HAS_STATE relationship with startDate as the current/given date. It will also create a new relationship between the new and the last State called PREVIOUS, with the old date as a property. If the given State is not related with the given Entity, an error will occur. If a custom relationship exists between the current State and a R node, that relationship is kept on the updated State if useCurrentRel is set to true`` otherwise it will use the given State one.

Details

Name`

graph.versioner.patch.from

Parameters

name necessity detail
entity mandatory The entity node to operate with.
state mandatory The State used to patch the current state from.
useCurrentRel optional Default value true. If true it will keep the custom relationships of the current State on the patched one, if `false it will use the passed state’s one.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node Node

Example call

MATCH (d:Device)-[:HAS_STATE]->(s:State {code:2}) WITH d,s CALL graph.versioner.patch.from(d, s, true, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

get current path

This procedure is used to retrieve the current path: by a given Entity node, it will return a path formed by the Entity node, the State node ant the CURRENT relationship.

This is how the returned path looks like:

Get Current Path

Details

Name

graph.versioner.get.current.path

Parameters

name necessity detail
entity mandatory The entity node to operate with.

Return value

name type
path Path

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.current.path(d) YIELD path RETURN path

get current state

This procedure is used to retrieve the current State node: by a given Entity node.

Details

Name

graph.versioner.get.current.state

Parameters

name necessity detail
entity mandatory The entity node to operate with.

Return value

name type
node Node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.current.state(d) YIELD node RETURN node

get all

This procedure is used to retrieve all Entity’s history in a path, including the Entity node, all the State nodes, CURRENT and PREVIOUS relationships.

Here is how the returned path looks like:

Get All

Details

Name

graph.versioner.get.all

Parameters

name necessity detail
entity mandatory The entity node to operate with.

Return value

name type
path Path

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.all(d) YIELD path RETURN path

get by label

This procedure is used to retrieve all Entity State nodes, that have the given Label.

Details

Name

graph.versioner.get.by.label

Parameters

name necessity detail
entity mandatory The entity node to operate with.
label mandatory The additional State nodes label.

Return value

name type
node node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.by.label(d, 'Error') YIELD node RETURN node

get by date

This procedure is used to retrieve a specific Entity State node, that has been created at the given date.

Details

Name

graph.versioner.get.by.date

Parameters

name necessity detail
entity mandatory The entity node to operate with.
date mandatory The LocalDateTime value of a given date.

Return value

name type
node node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.by.date(d, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

get nth state

This procedure is used to retrieve the nth Entity State node.

Details

Name

graph.versioner.get.nth.state

Parameters

name necessity detail
entity mandatory The entity node to operate with.
nth mandatory A number representing the nth State that must be returned.

Return value

name type
node node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.get.nth.state(d, 3) YIELD node RETURN node

rollback

This procedure is used to rollback the current Entity State node, to the first available one. The first available State node, is the first previous node, without an existing ROLLBACK relationship. If only one current State is available, null will be returned. If date is given, that value will be used instead of the current one. This procedure will also take care about custom relationships’ rollback.

Details

Name

graph.versioner.rollback

Parameters

name necessity detail
entity mandatory The entity node to operate with.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.rollback(d, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

rollback to

This procedure is used to rollback the current Entity State node, to the given one. If the given State is the current one, or if it already has a CURRENT relationship, null will be returned. If date is given, that value will be used instead of the current one. If the given State is not related with the given Entity, an error will occur.` This procedure will also take care about custom relationships’ rollback.

Details

Name

graph.versioner.rollback.to

Parameters

name necessity detail
entity mandatory The entity node to operate with.
state mandatory The State node to rollback to.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node node

Example call

MATCH (d:Device)-[:HAS_STATE]->(s:State {code:2}) WITH d, s CALL graph.versioner.rollback.to(d, s, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

rollback nth

This procedure is used to rollback the current Entity State node, to the nth one. If the nth value is 0, null will be returned. If date is given, that value will be used instead of the current one. This procedure will also take care about custom relationships’ rollback.

Details

Name

graph.versioner.rollback.nth

Parameters

name necessity detail
entity mandatory The entity node to operate with.
nth mandatory A number representing the nth State to rollback to.
date optional The LocalDateTime value of a given date, used instead of the current one.

Return value

name type
node node

Example call

MATCH (d:Device) WITH d CALL graph.versioner.rollback.nth(d, 3, localdatetime('1988-10-27T02:46:40')) YIELD node RETURN node

diff

This procedure will offer a list of operation needed in order to obtain a given State node, from another given one. It will return all the properties of both nodes, coupled with an operation. Those possible operations are:

Details

Name

graph.versioner.diff

Parameters

name necessity detail
stateFrom mandatory The starting State node for the comparison.
stateTo mandatory The ending State node for the comparison.

Return value

name type
operation string
label string
oldValue object
newValue object

Example call

MATCH (stateFrom:State {code:2}), (stateTo:State {code:3}) WITH stateFrom, stateTo CALL graph.versioner.diff(stateFrom, stateTo) YIELD operation, label, oldValue, newValue RETURN operation, label, oldValue, newValue

diff from previous

This procedure will offer a list of operation needed in order to obtain a given State node, from its previous one. It will return all the properties of both nodes, coupled with an operation (see diff] procedure for more information).

Details

Name

graph.versioner.diff.from.previous

Parameters

name necessity detail
state mandatory The ending State node for the comparison.

Return value

name type
operation string
label string
oldValue object
newValue object

Example call

MATCH (s:State {code:2}) WITH s CALL graph.versioner.diff.from.previous(s) YIELD operation, label, oldValue, newValue RETURN operation, label, oldValue, newValue

diff from current

This procedure will offer a list of operation needed in order to obtain a given State node, from the current one. It will return all the properties of both nodes, coupled with an operation (see diff] procedure for more information).

Details

Name

graph.versioner.diff.from.current

Parameters

name necessity detail
state mandatory The starting State node for the comparison.

Return value

name type
operation string
label string
oldValue object
newValue object

Example call

MATCH (s:State {code:2}) WITH s CALL graph.versioner.diff.from.current(s) YIELD operation, label, oldValue, newValue RETURN operation, label, oldValue, newValue

relationship create

This procedure is used to connect two Graph Versioner entities with a versioned Neo4j relationship. This method creates a new CURRENT state for the Entity, and connects it with the R state of the destination Entity. The procedure will return the newly created relationship. If date is given , date of the new state including the relationship will be the specified one.

Details

Name

graph.versioner.relationship.create

Parameters

name necessity details
entitySource, mandatory The source entity, where the new state will be created.
entityDestination mandatory The destination entity, containing the R node where the new relationship will point.
type mandatory The type of the relationship that will be created.
{key:value,...} optional A Map representing the relationship properties.
date optional The LocalDateTime of creation of the relationship.

Return value

name type
relationship Relationship

Example call

MATCH (person:Entity:Person), (city:Entity:City) WITH person, city CALL graph.versioner.relationship.create(person, city, 'LIVES_IN') YIELD relationship RETURN relationship

relationship delete

This procedure is used to delete a relationship between two Graph Versioner entities. This method creates a new CURRENT state for the Entity, and removes the previous custom relationship of the given type. The procedure will return true if the relationship was deleted successfully, false otherwise. If date is given , date of the new state including the relationship will be the specified one.

Details

Name

graph.versioner.relationship.delete

Parameters

name necessity details
entitySource, mandatory The source entity, where the new state will be created.
entityDestination mandatory The destination entity, containing the R node where the new relationship will point.
type mandatory The type of the relationship that will be deleted.
date optional The LocalDateTime of creation of the relationship.

Return value

name type
result Boolean

Example call

MATCH (person:Entity:Person), (city:Entity:City) WITH person, city CALL graph.versioner.relationship.delete(person, city, 'LIVES_IN') YIELD result RETURN result

relationships createTo

This procedure is used to connect one Graph Versioner entitiy to many Graph Versioner entities with a versioned Neo4j relationship. This method creates a new CURRENT state for the Entity, and connects it with the R state of the destination Entities. The procedure will return the newly created relationships. If date is given , date of the new state including the relationship will be the specified one.

Details

Name

graph.versioner.relationships.createTo

Parameters

name necessity details
entitySource, mandatory The source entity, where the new state will be created.
entityDestinations mandatory A list of the destination entities, containing the R node where the new relationship will point.
{key:value,...} optional A Map representing the relationship properties.
date optional The LocalDateTime of creation of the relationship.

Return value

name type
relationship Relationship

Example call

MATCH (person:Entity:Person), (city1:Entity:City), (city2:Entity:City) WITH person, [city1, city2] AS cities CALL graph.versioner.relationships.createTo(person, cities) YIELD relationship RETURN relationship

relationships createFrom

This procedure is used to connect many Graph Versioner entities to one Graph Versioner entity with a versioned Neo4j relationship. This method creates a new CURRENT state for the Entities, and connects it with the R state of the destination Entity. The procedure will return the newly created relationships. If date is given , date of the new state including the relationship will be the specified one.

Details

Name

graph.versioner.relationships.createFrom

Parameters

name necessity details
entitySources, mandatory A list of the source entities, where the new state will be created.
entityDestination mandatory The destination entity, containing the R node where the new relationship will point.
{key:value,...} optional A Map representing the relationship properties.
date optional The LocalDateTime of creation of the relationship.

Return value

name type
relationship Relationship

Example call

MATCH (person1:Entity:Person), (person2:Entity:Person), (city:Entity:City) WITH [person1, person2] AS persons, city CALL graph.versioner.relationships.createFrom(persons, city) YIELD relationship RETURN relationship

relationships delete

This procedure is used to delete relationships from a Graph Versioner entity. This method creates a new CURRENT state for the Entity, and removes the previous custom relationships of the given type. The procedure will return true if the relationship was deleted successfully, false otherwise. If date is given , date of the new state including the relationship will be the specified one.

Details

Name

graph.versioner.relationships.delete

Parameters

name necessity details
entitySource, mandatory The source entity, where the new state will be created.
relationshipTypes mandatory A list of relationship types that must be deleted.
date optional The LocalDateTime of creation of the relationship.

Return value

name type
result Boolean

Example call

MATCH (person:Entity:Person) WITH person, ["LIVES_IN", "MARRIED_WITH"] as types CALL graph.versioner.relationships.delete(person, types) YIELD result RETURN result

Feedback

We would appreciate your feedback about our Versioner Core, how to improve and fix (we hope not so many!) any bad things. Say yours in the issue section.