ex_cypher v0.2.0 ExCypher
A DSL to make it easy to integrate other apps to Neo4J applications.
This module provide a clean API to build queries using CYPHER query language, which is largely used by Neo4j
Usage:
First of all, add import ExCpyher to the top of your module, so that
cypher macro is available to your functions, then you can run it to generate
you cypher queries.
Examples:
MATCH statements:
- Matching nodes without returning a specific property
iex> cypher do: match(node(:n))
"MATCH (n)"
iex> cypher do: match(node(:p, [:Person]))
"MATCH (p:Person)"
iex> cypher do
...> match(node(:p, [:Person], %{name: "bob"}))
...> end
~S[MATCH (p:Person {"name":"bob"})]
We already support associations too:
iex> cypher do
...> match node(:p, [:Person]) -- node(:c, [:Company])
...> end
"MATCH (p:Person)--(c:Company)"
iex> cypher do
...> match node(:p, [:Person]) -- rel(:WORKS_IN) -- node(:c, [:Company])
...> return :p
...> end
"MATCH (p:Person)-[WORKS_IN]-(c:Company) RETURN p"
Can use arrow-syntax to represent directed associations, but must use
parenthesis arround the match arguments so that elixir correctly
builds the AST with the correct precedence structure
iex> cypher do
...> match (node(:p, [:Person]) -- rel(:WORKS_IN) -> node(:c, [:Company]))
...> end
"MATCH (p:Person)-[WORKS_IN]->(c:Company)"
iex> cypher do
...> match (node(:c, [:Company]) <- rel(:WORKS_IN) -- node(:p, [:Person]))
...> end
"MATCH (c:Company)<-[WORKS_IN]-(p:Person)"
ORDERing and LIMITing queries:
You can order and/or limit your query results with order and limit
commands:
iex> cypher do
...> match node(:s, [:Sharks])
...> order s.name
...> limit 10
...> return s.name, s.population
...> end
"MATCH (s:Sharks) ORDER BY s.name LIMIT 10 RETURN s.name, s.population"
Also, you can choose the ordering direction of your matched nodes with a tuple syntax:
iex> cypher do
...> match node(:s, [:Sharks])
...> order {s.name, :asc}, {s.age, :desc}
...> return :s
...> end
"MATCH (s:Sharks) ORDER BY s.name ASC, s.age DESC RETURN s"
CREATE and MERGE stuff
In order to create new nodes into your database, you can use the following syntax:
iex> cypher do
...> create node(:p, [:Player], %{nick: "like4boss", score: "100"})
...> return p.name
...> end
~S[CREATE (p:Player {"nick":"like4boss","score":"100"}) RETURN p.name]
However, if you want to match pre-existing nodes instead of creating new ones, you can use merge, as follows:
iex> cypher do
...> merge node(:p, [:Player], %{nick: "like4boss"})
...> merge node(:p2, [:Player], %{nick: "marioboss"})
...> return p.name
...> end
~S|MERGE (p:Player {"nick":"like4boss"}) MERGE (p2:Player {"nick":"marioboss"}) RETURN p.name|
iex> cypher do
...> merge node(:p, [:Player], %{nick: "like4boss"})
...> merge node(:p2, [:Player], %{nick: "marioboss"})
...> merge (node(:p) -- rel([:IN_LOBBY]) -> node(:p2))
...> return p.name
...> end
~S|MERGE (p:Player {"nick":"like4boss"}) MERGE (p2:Player {"nick":"marioboss"}) MERGE (p)-[:IN_LOBBY]->(p2) RETURN p.name|
Link to this section Summary
Functions
Saves a query line into the query buffer (where the other query lines) are being kept isolated.
Wraps contents of a Cypher query and returns the query string.
Parses each command-line from the cypher macro's block
Link to this section Functions
Saves a query line into the query buffer (where the other query lines) are being kept isolated.
Since those query lines break with elixir's language syntax, we cannot
call unquote on them, thus making the macro approach necessary.
Also, buffer pid is on another scope, and cannot be accessed directly
by the parse function.
Wraps contents of a Cypher query and returns the query string.
parse(stmt)
Parses each command-line from the cypher macro's block