Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #399 - Missing detailed documentation for Graph Refactoring procedures #402

Merged
merged 1 commit into from
Apr 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
276 changes: 265 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 @@ -627,6 +627,260 @@ 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 nodes that we have created before and their clones

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

.Clone nodes with relationship

We create a dataset of two different nodes of type `Actor` connected with other two different node of type `Movie`

[source,cypher]
----
CREATE (k:Actor {name:'Keanu Reeves'})-[:ACTED_IN {role:'Neo'}]->(m:Movie {title:'The Matrix'}),
(t:Actor {name:'Tom Hanks'})-[:ACTED_IN {role:'Forrest'}]->(f:Movie {title:'Forrest Gump'}) RETURN *
----

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

[source,cypher]
----
MATCH (k:Actor {name:'Keanu Reeves'}), (t:Actor {name:'Tom Hanks'})
CALL apoc.refactor.cloneNodesWithRelationships([k,t]) YIELD input, output RETURN *
----

As result we have a copy of the 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

[source,cypher]
----
CREATE (:Person {prop: 'Y', name:'A'}),(:Person {prop: 'Yes', name:'B'}),(:Person {prop: 'NO', name:'C'}),(:Person {prop: 'X', name:'D'})
----

As a resul we have four nodes with different properties `prop` 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 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 @@ -866,23 +1120,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 @@ -967,9 +1221,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 @@ -1045,4 +1299,4 @@ RETURN path, weight
MATCH (n:Person)
----

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