-
Notifications
You must be signed in to change notification settings - Fork 276
Neo4j::Cypher Start
Every query describes a pattern, and in that pattern one can have multiple start points. A start point is a relationship or a node that form the starting points for a pattern match. You can either introduce start points by id, or by index lookups.
In Neo4j::Core and Neography (with the neo4j-cypher adapter) you can also give the start nodes as ruby arguments for the DSL Example:
Neo4j.query(Person.find_by_name('andreas')) {|me| me > ':friends' > node(:myfriends).ret})
See also the Neo4j Documetation.
Binding a node as a start point can be done with the node
method.
Example:
node(3)
Will generate START v0=node(3) RETURN v0
. Remember that the last value evaluated will be the return value (when possible).
As shown in the example above the DSL will automatically create a new variable, v0
.
There is a #as
method which allows you to specify the variable name.
The #as
method is available on nodes, relationships, functions (like count) and paths.
Example:
node(3).as(:x)
Will generate START x = node(3) RETURN x
Nodes and Relationships can also be used in WHERE and MATCH clauses. To express that you want any node use the node or rel without any argument.
Example:
node(3) <=> node
which is same as: START v1=node(1) MATCH v3 = (v1)--(v2) RETURN v3
The spaceship operator <=>
means match any outgoing or incoming relationship.
The #as
method can be used if you need to specify the name of the variable.
Example:
node(3) <=> node.as(:friends)
Which will instead generate the following string START v1=node(1) MATCH v2 = (v1)--(friend) RETURN v2
A shorter way of doing this is using ruby symbols:
node(3) <=> node(:friends)
An even short way of doing this is using ruby symbols.
node(3) <=> :friends
The rel
is normally used for matching purpose, but can also be used to specify a start relationship.
Example:
rel 1,2,3
Is the same as START v1=relationship(1,2,3) RETURN v1
The method rel
with no arguments or the rel?
method specifies an optional relationship.
Match any outgoing relationships from node 3:
node(3) > rel > :person
This is same as START v1=node(3) MATCH v2 = (v1)-[?]->(person) RETURN v2
To match a relationship type is given as argument(s) for the rel
method.
node(3) > rel(:friends) > node(:person)
Which is same as START v1=node(3) MATCH v2 = (v1)-[:`friends`]->(person) RETURN v2 Notice that the relationship type is escaped so that you can have white spaces etc as relationship types.
Multiple relationship types is simply specified by more arguments for the rel method. Example:
node(1) > rel(:friends, :work, :family) > node(:person)
Which will generate the following: 'START v1=node(1) MATCH v2 = (v1)-[:`friends`|`work`|`family`]->(person) RETURN v2'
This can also be combined with the #as
method.
node(1) > rel(:friends, :work, :family).as(:foo) > node(:person)
ret :foo
Which will generate START v1=node(1) MATCH (v1)-[foo:`friends`|`work`|`family`]->(person) RETURN foo
If a symbol is specified when an relationship is expected it will automatically be converted to a relationship.
This means that instead of writing node(3) > rel(:r) > :person
you can write:
node(3) > :r > :person
If a relationship is specified as a string it will be used in the match clause as is.
Example: Return the path from node 3 navigating outgoing relationship of type friend
or type knows
depth one.
node(3) > rel(':friend|knows') > 'bla'
Will generate START v1=node(3) MATCH v2 = (v1)-[:friend|knows]->(bla) RETURN v2
String will automatically be converted to a relationship pattern. This means that the example above can be written like this:
node(3) > ':friend|knows' > 'bla'
You can also use relationship as variables. Let say you want to return all the relationships instead from the query above. This can be done like this:
node(3) > rel(':friend|knows').as(:foo) > :person
Which is the same as START v1=node(3) MATCH v2 = (v1)-[foo:friend|knows]->(person) RETURN v2
This allows you to identify an relationship, which for example can be used later as a return value.
Example:
node(3) > rel(':friend|knows').as(:foo) > :person
ret :foo
Which is same as:
node(3) > rel(':friend|knows').as(:foo).ret > :person
Which will generate START v1=node(3) MATCH (v1)-[foo:friend|knows]->(person) RETURN foo
See Neo4j::Cypher-Return
As a convenience method, use the rel? method to specify optional relationship. If the relationship is there, it is returned. If it’s not, nil is returned in it’s place.
For example: node 3 does not have any relationship of type knows
node(3).ret > rel?(:knows).as(:k).ret > :person
Generates cypher: START v1=node(3) MATCH (v1)-[k?:
knows]->(person) RETURN v1,k
When the query is executed it will return a node, and null, since the node has no outgoing knows
relationship.
Alternative, using the outgoing
method:
node(3).as(:me).outgoing(rel?(:knows).as(:knows)).ret(:me, :knows)
Generates: START me=node(3) MATCH (me)-[knows?:`knows`]->(v1) RETURN me,knows
Since you can inject your own nodes and relationship as argument to the Cypher DSL there is less needed to use the lookup
and query
methods.
Example of finding a single node using the lucene index 'myindex':
lookup('myindex', "desc", "A")
# same as "START n0=node:myindex(desc="A") RETURN n0"
Example of using the lucene query syntax:
query('myindex', "name:A")
# same as "START n0=node:myindex(name:A) RETURN n0])"
See query_rel
and lookup_rel
for lucene queries on relationships.
Notice that if you use Neo4j::Core (or Neo4j::Rails) you can use the class instead of the string describing the name of the index, see Neo4j::Core-Cypher
WARNING: Much of the information in this wiki is out of date. We are in the process of moving things to readthedocs
- Project Introduction
- Neo4j::ActiveNode
- Neo4j::ActiveRel
- Search and Scope
- Validation, Uniqueness, and Case Sensitivity
- Indexing VS Legacy Indexing
- Optimized Methods
- Inheritance
- Core: Nodes & Rels
- Introduction
- Persistence
- Find : Lucene
- Relationships
- Third Party Gems & extensions
- Scaffolding & Generators
- HA Cluster