You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2015/06/03 02:12:30 UTC

[25/50] [abbrv] incubator-tinkerpop git commit: added Neo4jGremlin back to the AsciiDocs.

added Neo4jGremlin back to the AsciiDocs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/ff6067d6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/ff6067d6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/ff6067d6

Branch: refs/heads/preprocessor
Commit: ff6067d6d645020252d7c1ab0bd9cb64d3d2bd1b
Parents: 00fc75d
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri May 29 14:34:57 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri May 29 14:34:57 2015 -0600

----------------------------------------------------------------------
 docs/src/implementations.asciidoc | 186 +++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ff6067d6/docs/src/implementations.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/implementations.asciidoc b/docs/src/implementations.asciidoc
index e61fefb..c4a087a 100644
--- a/docs/src/implementations.asciidoc
+++ b/docs/src/implementations.asciidoc
@@ -508,6 +508,192 @@ TinkerGraph has several settings that can be provided on creation via `Configura
 
 The `IdManager` settings above refer to how TinkerGraph will control identifiers for vertices, edges and vertex properties.  There are several options for each of these settings: `ANY`, `LONG`, `INTEGER`, `UUID`, or the fully qualified class name of an `IdManager` implementation on the classpath.  When not specified, the default values for all settings is `ANY`, meaning that the graph will work with any object on the JVM as the identifier and will generate new identifiers from `Long` when the identifier is not user supplied.  TinkerGraph will also expect the user to understand the types used for identifiers when querying, meaning that `g.V(1)` and `g.V(1L)` could return two different vertices.  `LONG`, `INTEGER` and `UUID` settings will try to coerce identifier values to the expected type as well as generate new identifiers with that specified type.
 
+[[neo4j-gremlin]]
+Neo4j-Gremlin
+-------------
+
+[source,xml]
+----
+<dependency>
+   <groupId>org.apache.tinkerpop</groupId>
+   <artifactId>neo4j-gremlin</artifactId>
+   <version>x.y.z</version>
+</dependency>
+----
+
+link:http://neotechnology.com[Neo Technology] are the developers of the OLTP-based link:http://neo4j.org[Neo4j graph database].
+
+CAUTION: Unless under a commercial agreement with Neo Technology, Neo4j is licensed as link:http://en.wikipedia.org/wiki/Affero_General_Public_License[AGPL]. The `neo4j-gremlin` module is licensed Apache2 because it only references the Apache2-licensed Neo4j API (not implementation). Note that neither the <<gremlin-console,Gremlin Console>> nor <<gremlin-server,Gremlin Server>> distribute with the Neo4j binaries. To access the Neo4j binaries, use the `:install` command to download binaries from link:http://search.maven.org/[Maven Central Repository].
+
+[source,groovy]
+----
+gremlin> :install org.apache.tinkerpop neo4j-gremlin x.y.z
+==>loaded: [org.apache.tinkerpop, neo4j-gremlin, x.y.z]
+gremlin> :plugin use tinkerpop.neo4j
+==>tinkerpop.neo4j activated
+gremlin> g = Neo4jGraph.open('/tmp/neo4j')
+==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
+----
+
+For those leveraging Neo4j High Availability, configure `Neo4jGraph` for "HA mode" by setting the `gremlin.neo4j.ha` flag to `true` in the `Configuration` object passed to `Neo4jGraph.open()`.  Note that when the flag is set (by default it is `false`), the `Neo4jGraph` instance expects HA configuration settings to be present.  As with embedded Neo4j, HA configuration keys should be prefixed with `gremlin.neo4j.conf`.  Please consult Neo4j documentation for more information on link:http://docs.neo4j.org/chunked/stable/ha.html[High Availability] configuration.
+
+IMPORTANT: `Neo4jGraph` supports both meta- and multi-properties (see <<_vertex_properties,vertex properties>>). However, these are implemented by making use of "hidden" Neo4j nodes. For example, when a vertex has multiple "name" properties, each property is a new node (multi-properties) which can have properties attached to it (meta-properties). As such, the underlying representation may become difficult to query directly using another graph language such as Cypher. The default setting is to disable multi- and meta-properties. However, if this feature is desired, then it can be activated via `gremlin.neo4j.metaProperties` and `gremlin.neo4j.multiProperties` configurations being set to `true`. Once the configuration is set, it can not be changed for the lifetime of the graph.
+
+TIP: To host Neo4j in Gremlin Server, the dependencies must first be "installed" or otherwise copied to the Gremlin Server path.  The automated method for doing this would be to execute `bin/gremlin-server.sh -i org.apache.tinkerpop neo4j-gremlin x.y.z`.
+
+Indices
+~~~~~~~
+
+Neo4j 2.x supports two types of indices: link:http://docs.neo4j.org/chunked/stable/query-schema-index.html[schema indices] and link:http://docs.neo4j.org/chunked/stable/auto-indexing.html[automatic indices]. Automatic indices have been around since Neo4j 1.x and automatically index an element based on a pre-defined property keys. Schema indices are new to Neo4j 2.x and leverage vertex labels to partition the index space. TinkerPop3 does not provide method interfaces for defining schemas/indices for the underlying graph system. Thus, in order to create indices, the Neo4j API is leveraged.
+
+NOTE: `Neo4jGraph` will attempt to discern which indices to use when executing a traversal of the form `g.V().has()`. The general order of checking is: schema indices, automatic indices, label grouping linear-scan iteration, full linear-scan iteration.
+
+Using Schema Indices
+^^^^^^^^^^^^^^^^^^^^
+
+The Gremlin-Console session below demonstrates schema indices. For more information, please refer to the Neo4j documentation:
+
+* Manipulating schema indices with link:http://docs.neo4j.org/chunked/stable/query-schema-index.html[Cypher].
+* Manipulating schema indices with the Neo4j link:http://docs.neo4j.org/chunked/stable/tutorials-java-embedded-new-index.html[Java API].
+
+[source,groovy]
+gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
+==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
+gremlin> graph.tx().open() // direct Neo4j access requires explicit transaction creation
+==>null
+gremlin> import org.neo4j.graphdb.*
+...
+gremlin> graph.getBaseGraph().schema().indexFor(DynamicLabel.label('person')).on('name').create()
+==>IndexDefinition[label:person, on:name]
+gremlin> graph.tx().commit()
+==>null
+gremlin> graph.addVertex(label,'person','name','marko')
+==>v[0]
+gremlin> graph.addVertex(label,'dog','name','puppy')
+==>v[1]
+gremlin> g = graph.traversal(standard())
+==>graphtraversalsource[neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]], standard]
+gremlin> g.V().hasLabel('person').has('name','marko').values('name')
+==>marko
+
+Below demonstrates the runtime benefits of indices and demonstrates how if there is no defined schema index (only vertex labels), a linear scan of the vertex-label partition is still faster than a linear scan of all vertices.
+
+[source,groovy]
+gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
+==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
+gremlin> graph.tx().open()
+==>null
+gremlin> import org.neo4j.graphdb.*
+...
+gremlin> graph.getBaseGraph().schema().indexFor(DynamicLabel.label('artist')).on('name').create() <1>
+==>IndexDefinition[label:artist, on:name]
+gremlin> graph.tx().commit()
+==>null
+gremlin> graph.io().readGraphML('data/grateful-dead.xml')
+==>null
+gremlin> g = graph.traversal(standard())
+==>graphtraversalsource[neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]], standard]
+gremlin> clock(1000){g.V().hasLabel('artist').has('name','Garcia').next()}  <2>
+==>0.0585639999999997
+gremlin> clock(1000){g.V().has('name','Garcia').next()} <3>
+==>0.6039889999999992
+gremlin> g.getBaseGraph().schema().getIndexes(DynamicLabel.label('artist')).iterator().next().drop() <4>
+==>null
+gremlin> g.tx().commit()
+==>null
+gremlin> clock(1000){g.V().hasLabel('artist').has('name','Garcia').next()} <5>
+==>0.26470499999999936
+gremlin> clock(1000){g.V().has('name','Garcia').next()} <6>
+==>0.6293959999999993
+
+<1> Create a schema index for all artist vertices on their name property.
+<2> Find all artists whose name is Garcia which uses the pre-defined schema index.
+<3> Find all vertices whose name is Garcia which requires a linear scan of all the data in the graph.
+<4> Drop the created index schema.
+<5> Find all artists whose name is Garcia which does a linear scan of the artist vertex-label partition.
+<6> Find all vertices whose name is Garcia which requires a linear scan of all the data in the graph.
+
+
+Using Automatic Indices
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The Gremlin-Console session below demonstrates automatic indices. For more information, please refer to the Neo4j documentation:
+
+* Manipulating automatic indices with the Neo4j link:http://docs.neo4j.org/chunked/stable/auto-indexing.html[Java API].
+
+[source,groovy]
+gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
+==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
+gremlin> graph.getBaseGraph().index().getNodeAutoIndexer().startAutoIndexingProperty('name')
+==>null
+gremlin> graph.getBaseGraph().index().getNodeAutoIndexer().setEnabled(true)
+==>null
+gremlin> graph.addVertex(label,'person','name','marko')
+==>v[0]
+gremlin> graph.addVertex(label,'dog','name','puppy')
+==>v[1]
+gremlin> g = graph.traversal(standard())
+==>graphtraversalsource[neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]], standard]
+gremlin> g.V().hasLabel('person').has('name','marko').values('name')
+==>marko
+
+WARNING: The preferred method for dealing with automatic indices in Neo4j is via `Neo4jGraph.open()` configuration as opposed to runtime updating as demonstrated above. This is because with runtime updating, index information is not propagated across Neo4j connections.
+
+Cypher
+~~~~~~
+
+image::gremlin-loves-cypher.png[width=400]
+
+NeoTechnology are the creators of the graph pattern-match query language link:http://www.neo4j.org/learn/cypher[Cypher]. It is possible to leverage Cypher from within Gremlin by using the `Neo4jGraph.cypher()` graph traversal method.
+
+[source,groovy]
+gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
+==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
+gremlin> graph.io().readGryo('data/tinkerpop-modern.kryo')
+==>null
+gremlin> graph.cypher('MATCH (a {name:"marko"}) RETURN a')
+==>[a:v[0]]
+gremlin> graph.cypher('MATCH (a {name:"marko"}) RETURN a').select('a').out('knows').values('name')
+==>vadas
+==>josh
+
+Thus, like <<match-step,`match()`>>-step in Gremlin, it is possible to do a declarative pattern match and then move back into imperative Gremlin.
+
+IMPORTANT: For those developers using <<gremlin-server,Gremlin Server>> against Neo4j, it is possible to do Cypher queries by simply placing the Cypher string in `graph.cypher(...)` before submission to the server.
+
+Multi-Label
+~~~~~~~~~~~
+
+TinkerPop3 requires every `Element` to have a single, immutable string label (i.e. a `Vertex`, `Edge`, and `VertexProperty`). In Neo4j, a `Node` (vertex) can have an link:http://neo4j.com/docs/stable/graphdb-neo4j-labels.html[arbitrary number of labels] while a `Relationship` (edge) can have one and only one. Furthermore, in Neo4j, `Node` labels are mutable while `Relationship` labels are not. In order to handle this mismatch, three `Neo4jVertex` specific methods exist in Neo4j-Gremlin.
+
+[source,java]
+public Set<String> labels() // get all the labels of the vertex
+public void addLabel(final String label) // add a label to the vertex
+public void removeLabel(final String label) // remove a label from the vertex
+
+An example use case is presented below.
+
+[source,java]
+----
+Neo4jVertex v = (Neo4jVertex) graph.addVertex("human::animal");
+assertEquals("animal::human",v.label()) // standard Vertex.label() method (note that labels are alphabetically sorted)
+assertEquals(2, v.labels().size()) // specific Neo4jVertex.labels() method
+assertTrue(v.labels().contains("human"))
+assertTrue(v.labels().contains("animal"))
+
+v.addLabel("organism") // specific Neo4jVertex.addLabel() method
+v.removeLabel("human") // specific Neo4jVertex.removeLabel() method
+assertEquals(2, v.labels().size()) // specific Neo4jVertex.labels() method
+assertTrue(v.labels().contains("animal"))
+assertTrue(v.labels().contains("organism"))
+
+v.addLabel("organism") // add a repeat
+v.addLabel("human") // remove a label that doesn't exist
+assertEquals(2, v.labels().size()) // specific Neo4jVertex.labels() method
+assertTrue(v.labels().contains("animal"))
+assertTrue(v.labels().contains("organism"))
+----
+
 [[hadoop-gremlin]]
 Hadoop-Gremlin
 --------------