Skip to content

Commit

Permalink
Fixes neo4j-contrib#399 - Missing detailed documentation for Graph Re…
Browse files Browse the repository at this point in the history
…factoring procedures
  • Loading branch information
DanielBerton committed Apr 19, 2017
1 parent 9d4abf1 commit e472a03
Show file tree
Hide file tree
Showing 24 changed files with 267 additions and 11 deletions.
Binary file added docs/img/apoc.refactor.categorize.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.categorize.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.cloneNodes.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.cloneNodes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.collapseNode.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.collapseNode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.extractNode.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.extractNode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.from.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.from.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.invert.call.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.invert.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.invert.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.mergeNodes.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.mergeNodes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.normalizeAsBoolean.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.setType.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.setType.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.to.dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apoc.refactor.to.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
278 changes: 267 additions & 11 deletions docs/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ RETURN name AS undocumented

// tag::procedurecount[]

To find the procedure count with the package in Neo4j:
To find the procedure count with the package in Neo4j:

image::{img}/apoc.dbms.procedure.count.jpg[width=600]

Expand Down Expand Up @@ -623,6 +623,262 @@ TODO:
* merge nodes by label + property
* merge relationships

=== Graph Refactoring Examples

.Clone nodes

We create a dataset
[source,cypher]
----
CREATE (f:Foo{name:'Foo'}),(b:Bar{name:'Bar'})
----

As result we have two nodes

image::{img}/apoc.refactor.cloneNodes.dataset.png[width=800]

[source,cypher]
----
MATCH (f:Foo{name:'Foo'}),(b:Bar{name:'Bar'}) WITH f,b
CALL apoc.refactor.cloneNodes([f,b]) yield input, output RETURN *
----

As result we have the two node that we have created before and their clone

image::{img}/apoc.refactor.cloneNodes.png[width=800]

.Clone nodes with relationship

We create a dataset
[source,cypher]
----
CREATE (f:Foo {name:'Foo'})-[r:FOOBAR {since: 2001}]->(b:Bar {name:'Bar'}) RETURN f,b
----

As result we have two nodes connected by a relationship

image::{img}/apoc.refactor.cloneNodesWithRelationship.dataset.png[width=800]

[source,cypher]
----
MATCH (f:Foo {name:'Foo'}),(b:Bar {name:'Bar'})
CALL apoc.refactor.cloneNodesWithRelationships([f,b]) YIELD input, output RETURN *
----

As result we have a copy of nodes and relationships

image::{img}/apoc.refactor.cloneNodesWithRelationships.png[width=800]

.Merge nodes

We create two nodes with different properties

[source,cypher]
----
CREATE (f:Person {name:'Foo'}), (b:Person {surname:'Bar'}) RETURN f,b
----

image::{img}/apoc.refactor.mergeNodes.dataset.png[width=800]

Now we want to merge these nodes into one

[source,cypher]
----
MATCH (f:Person {name:'Foo'}), (b:Person {surname:'Bar'})
CALL apoc.refactor.mergeNodes([f,b])
YIELD node RETURN node
----

image::{img}/apoc.refactor.mergeNodes.png[width=800]

Thus we have one node with both properties `name` and `surname`

.Redirect relationship to

We start with two nodes related each other with a relationship. We create a new node which we will use to redirect the relationship like end node

[source,cypher]
----
CREATE (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar)
CREATE (p:Person {name:'Antony'})
RETURN *
----

image::{img}/apoc.refactor.to.dataset.png[width=800]

[source,cypher]
----
MATCH (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar) with id(rel) as id
MATCH (p:Person {name:'Antony'}) with p as p
MATCH ()-[r]->(), (p:Person) CALL apoc.refactor.to(r, p) YIELD input, output RETURN *
----

image::{img}/apoc.refactor.to.png[width=800]

Now the relationship is towards the new node `Person`

.Redirect relationship from

We start with two nodes related each other with a relationship. We create a new node which we will use to redirect the relationship like start node

[source,cypher]
----
CREATE (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar)
CREATE (p:Person {name:'Antony'})
RETURN *
----

image::{img}/apoc.refactor.from.dataset.png[width=800]

[source,cypher]
----
MATCH (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar) with id(rel) as id
MATCH (p:Person {name:'Antony'}) with p as p
MATCH ()-[r]->(), (p:Person) CALL apoc.refactor.from(r, p) YIELD input, output RETURN *
----

image::{img}/apoc.refactor.from.png[width=800]

Now the relationship starts from the new node `Person` from the old node `Bar`

.Invert relationship

We start with two nodes connected by a relationship

[source,cypher]
----
CREATE (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar)
----

image::{img}/apoc.refactor.invert.dataset.png[width=800]

Now we want to invert the relationship direction

[source,cypher]
----
MATCH (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar) WITH id(rel) as id
MATCH ()-[r]->() WHERE id(r) = id
CALL apoc.refactor.invert(r) yield input, output RETURN *
----

image::{img}/apoc.refactor.invert.call.png[width=800]

image::{img}/apoc.refactor.invert.png[width=800]

.Set type

With a simple relationship between two node

[source,cypher]
----
CREATE (f:Foo)-[rel:FOOBAR]->(b:Bar)
----

image::{img}/apoc.refactor.setType.dataset.png[width=800]

we can change the relationship type from `FOOBAR` to `NEW-TYPE`

[source,cypher]
----
MATCH (f:Foo)-[rel:FOOBAR]->(b:Bar) with rel
CALL apoc.refactor.setType(rel, 'NEW-TYPE') YIELD input, output RETURN *
----

image::{img}/apoc.refactor.setType.png[width=800]

.Extract node from relationships

[source,cypher]
----
CREATE (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar)
----

image::{img}/apoc.refactor.extractNode.dataset.png[width=800]

We pass the ID of the relationship as parameter to extract a node

[source,cypher]
----
MATCH (f:Foo)-[rel:FOOBAR {a:1}]->(b:Bar) WITH id(rel) as id
CALL apoc.refactor.extractNode(id,['FooBar'],'FOO','BAR')
YIELD input, output RETURN *
----

image::{img}/apoc.refactor.extractNode.png[width=800]

.Collapse node to relationship

[source,cypher]
----
CREATE (f:Foo)-[:FOO {a:1}]->(b:Bar {c:3})-[:BAR {b:2}]->(f) WITH id(b) as id
CALL apoc.refactor.collapseNode(id,'FOOBAR')
YIELD input, output RETURN *
----

Before we have this situation

image::{img}/apoc.refactor.collapseNode.dataset.png[width=800]

And the result are

image::{img}/apoc.refactor.collapseNode.png[width=800]

The property of the two relationship and the property of the node are joined in one relationship that has the properties `a:1`, `b:2`, `name:Bar`

.Normalize As Boolean

We create a dataset

[source,cypher]
----
CREATE ({prop: 'Y', id:1}),({prop: 'Yes', id: 2}),({prop: 'NO', id: 3}),({prop: 'X', id: 4})
----

As a resul we have four nodes with different properties like `Y`, `Yes`, `NO`, `X`

image::{img}/apoc.refactor.normalizeAsBoolean.dataset.png[width=800]

Now we want to transform some properties into a boolean, `Y`, `Yes` into true and all the properties `NO` into false.
The other properties that don't match these possibilities will be set as `null`.

[source,cypher]
----
MATCH (n) CALL apoc.refactor.normalizeAsBoolean(n,'prop',['Y','Yes'],['NO']) WITH n ORDER BY n.id RETURN n.prop AS prop
----

image::{img}/apoc.refactor.normalizeAsBoolean.png[width=800]

.Categorize

First of all we create some nodes as dataset

[source,cypher]
----
CREATE (:Person {prop: 'A', k: 'a', id: 1}),
(:Person {prop: 'A', k: 'a', id: 2}),
(:Person {prop: 'C', k: 'c', id: 3}),
(:Person { id: 4}),
(:Person {prop: 'B', k: 'b', id: 5}),
(:Person {prop: 'C', k: 'c', id: 6})
----

As result we have six nodes with label 'Person' with different properties

image::{img}/apoc.refactor.categorize.dataset.png[width=800]

Now we want to transform the property `prop` into a separate node with label `Letter` and transfer the properties of the nodes `Person`: `prop` (now renamed in `name`) and `k`.
The nodes `Person` will keep only the propertie `id`, and will be connected with a relationship `IS_A` with the new nodes `Letter`.

[source,cypher]
----
CALL apoc.refactor.categorize('prop','IS_A',true,'Letter','name',['k'],1)
----

image::{img}/apoc.refactor.categorize.png[width=800]

The direction of the relationship (in this case outgoing) is defined by the third field, if `true` outgoing else incoming.
If a node doesn't has the property `prop` (like node with `id: 4`) it won't be managed.

=== Rename

Procedures set for renaming labels, relationship types, nodes and relationships' properties.
Expand Down Expand Up @@ -862,23 +1118,23 @@ Splits date (optionally, using given custom format) into fields returning a map

== Bitwise operations

// TODO function
// TODO function

Provides a wrapper around the java bitwise operations.
|===
| apoc.bitwise.op(a long, "operation", b long ) as <identifier>
| apoc.bitwise.op(a long, "operation", b long ) as <identifier>
|===

examples
|===
| operator | name | example | result
| a & b | AND | apoc.bitwise.op(60,"&",13) | 12
| a \| b | OR | apoc.bitwise.op(60,"\|",13) | 61
| operator | name | example | result
| a & b | AND | apoc.bitwise.op(60,"&",13) | 12
| a \| b | OR | apoc.bitwise.op(60,"\|",13) | 61
| a ^ b | XOR | apoc.bitwise.op(60,"&",13) | 49
| ~a | NOT | apoc.bitwise.op(60,"&",0) | -61
| a << b | LEFT SHIFT | apoc.bitwise.op(60,"<<",2) | 240
| a >> b | RIGHT SHIFT | apoc.bitwise.op(60,">>",2) | 15
| a >>> b | UNSIGNED RIGHT SHIFT | apoc.bitwise.op(60,">>>",2) | 15
| a >> b | RIGHT SHIFT | apoc.bitwise.op(60,">>",2) | 15
| a >>> b | UNSIGNED RIGHT SHIFT | apoc.bitwise.op(60,">>>",2) | 15
|===

== Path Expander
Expand Down Expand Up @@ -963,9 +1219,9 @@ For huge graphs a traverser can hog all the memory in the JVM, causing OutOfMemo



== Parallel Node Search
== Parallel Node Search

Utility to find nodes in parallel (if possible). These procedures return a single list of nodes or a list of 'reduced' records with node id, labels, and the properties where the search was executed upon.
Utility to find nodes in parallel (if possible). These procedures return a single list of nodes or a list of 'reduced' records with node id, labels, and the properties where the search was executed upon.

[cols="5m,4"]
|===
Expand Down Expand Up @@ -1041,4 +1297,4 @@ RETURN path, weight
MATCH (n:Person)
----

// end::overview[]
// end::overview[]

0 comments on commit e472a03

Please sign in to comment.