Typed representation of a Cypher query, and builders for constructing common patterns.
The struct holds an ordered list of typed clause structs and a params map.
Callers build a query via the builder functions, then pass it to
AshNeo4j.Cypher.render/1 or AshNeo4j.Cypher.run/1.
Clause structs
Read: Match, OptionalMatch, Where, With, Return, OrderBy, Skip, Limit
Write: Create, Merge, Set, Remove, Delete, DetachDelete
Summary
Types
A single property filter condition for node_read_filtered/2:
{property, operator_atom, value, case_insensitive?}
Functions
Appends a LIMIT clause. No-op when n is nil.
Appends an ORDER BY clause. No-op when terms is empty.
Appends a SKIP clause. No-op when n is nil or 0.
Per-record aggregate — returns one row per source node with the aggregate value.
Total aggregate — returns a single row with the aggregate value across all source nodes.
MATCH (s:L1:L2) [WHERE <conditions>] RETURN s — a single combination-query
branch, sized to fit inside a CALL { … } block.
Same as branch_node_read/3 but returns just the Neo4j internal id of s
(as sid) instead of the node itself. Used to cheaply materialise the id
set per branch in the in-memory orchestration path for INTERSECT / EXCEPT
combination queries.
Wraps a list of branch queries (built via branch_node_read/3) in a
CALL { … UNION/UNION ALL … } block followed by the outer OPTIONAL MATCH
enrichment and RETURN s, r, d.
CREATE (n:L1:L2 {props}) RETURN n
MATCH (n:L1:L2 {props}) DETACH DELETE n
MATCH (n:L1:L2 {props}) WHERE NOT guard1 AND NOT guard2 DETACH DELETE n
MATCH (n:Labels {props}) RETURN n
MERGE (n:Label {props}) RETURN n
MATCH (s:L1:L2) OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d
MATCH (s:L1:L2) WHERE id(s) IN $ids OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d.
MATCH (s:L1:L2) WHERE <conditions> OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d
MATCH (n:L1:L2 {props}) OPTIONAL MATCH (n)-[r]-(d) RETURN n, r, d
MATCH (s:SrcLabel {s_props}) OPTIONAL MATCH (d:DestLabel {d_props}) MERGE (s)-[r:EDGE]->(d) RETURN s, r, d
Relates two nodes, removing existing edges from source AND to destination.
Relates two nodes, first removing any existing edge of the same type pointing to the destination.
Relates two nodes, first removing any existing edge of the same type from the source.
Related-nodes query — returns one row per (source, destination) pair for expression-based aggregates that need full destination records for Elixir-side evaluation.
MATCH (s:SrcLabels)-[r:EdgeLabel]-(d:DestLabel) WHERE d.prop <op> $param WITH s MATCH (s)-[r0]-(d0) RETURN s, r0, d0
MATCH (s:SrcLabel {s_props})-[r:EDGE]->(d:DestLabel {d_props}) DELETE r RETURN s, d
MATCH (n:L1:L2 {match_props}) SET n += {set_props} REMOVE n.p1, n.p2 RETURN n
Types
@type clause() :: AshNeo4j.Cypher.Match.t() | AshNeo4j.Cypher.OptionalMatch.t() | AshNeo4j.Cypher.Create.t() | AshNeo4j.Cypher.Merge.t() | AshNeo4j.Cypher.Where.t() | AshNeo4j.Cypher.With.t() | AshNeo4j.Cypher.Set.t() | AshNeo4j.Cypher.Remove.t() | AshNeo4j.Cypher.Delete.t() | AshNeo4j.Cypher.DetachDelete.t() | AshNeo4j.Cypher.Return.t() | AshNeo4j.Cypher.OrderBy.t() | AshNeo4j.Cypher.Skip.t() | AshNeo4j.Cypher.Limit.t() | AshNeo4j.Cypher.Call.t()
A single property filter condition for node_read_filtered/2:
{property, operator_atom, value, case_insensitive?}
Functions
@spec add_limit(t(), pos_integer() | nil) :: t()
Appends a LIMIT clause. No-op when n is nil.
Appends an ORDER BY clause. No-op when terms is empty.
@spec add_skip(t(), non_neg_integer() | nil) :: t()
Appends a SKIP clause. No-op when n is nil or 0.
@spec aggregate_per_record( atom() | [atom()], atom(), [any()], [{atom(), atom(), atom()}], atom(), atom() | nil, atom(), boolean(), [{String.t(), any()}] ) :: t()
Per-record aggregate — returns one row per source node with the aggregate value.
MATCH (s:L1:L2) WHERE s.pk IN $agg_ids OPTIONAL MATCH (s)<path>(d) RETURN s.pk AS source_id, agg_fn AS name
path_segments is a list of {edge_label, direction, dest_label} tuples describing
the traversal from source to the node being aggregated.
@spec aggregate_total( atom() | [atom()], atom(), [any()], [{atom(), atom(), atom()}], atom(), atom() | nil, atom(), boolean(), [{String.t(), any()}] ) :: t()
Total aggregate — returns a single row with the aggregate value across all source nodes.
MATCH (s:L1:L2) WHERE s.pk IN $agg_ids OPTIONAL MATCH (s)<path>(d) RETURN agg_fn AS name
MATCH (s:L1:L2) [WHERE <conditions>] RETURN s — a single combination-query
branch, sized to fit inside a CALL { … } block.
No OPTIONAL MATCH (the outer combination query owns enrichment) and only
the s column is returned (Cypher's UNION/UNION ALL requires identical
column shapes across branches).
Supports param_prefix: per branch — pass distinct prefixes for distinct
branches so their param keys (b0_s_name_0 vs b1_s_name_0) don't collide
when merged.
Examples
iex> q = AshNeo4j.Cypher.Query.branch_node_read(:Place)
iex> {cypher, _} = AshNeo4j.Cypher.render(q)
iex> cypher
"MATCH (s:Place) RETURN s"
iex> q = AshNeo4j.Cypher.Query.branch_node_read(:Place, [{"name", :==, "Sydney", false}], param_prefix: "b0_")
iex> {cypher, params} = AshNeo4j.Cypher.render(q)
iex> cypher
"MATCH (s:Place) WHERE s.name = $b0_s_name_0 RETURN s"
iex> params
%{"b0_s_name_0" => "Sydney"}
Same as branch_node_read/3 but returns just the Neo4j internal id of s
(as sid) instead of the node itself. Used to cheaply materialise the id
set per branch in the in-memory orchestration path for INTERSECT / EXCEPT
combination queries.
Examples
iex> q = AshNeo4j.Cypher.Query.branch_node_read_ids(:Place, [{"name", :==, "Sydney", false}], param_prefix: "b0_")
iex> {cypher, _} = AshNeo4j.Cypher.render(q)
iex> cypher
"MATCH (s:Place) WHERE s.name = $b0_s_name_0 RETURN id(s) AS sid"
Wraps a list of branch queries (built via branch_node_read/3) in a
CALL { … UNION/UNION ALL … } block followed by the outer OPTIONAL MATCH
enrichment and RETURN s, r, d.
Branch params are merged into the outer query's params map. Branches are
rendered to Cypher strings before being placed in the Call clause.
Opts:
:union_type—:unionor:union_all(default:union_all)
Examples
iex> b0 = AshNeo4j.Cypher.Query.branch_node_read(:Place, [{"name", :==, "Sydney", false}], param_prefix: "b0_")
iex> b1 = AshNeo4j.Cypher.Query.branch_node_read(:Place, [{"name", :==, "Melbourne", false}], param_prefix: "b1_")
iex> q = AshNeo4j.Cypher.Query.combination_block([b0, b1])
iex> {cypher, params} = AshNeo4j.Cypher.render(q)
iex> cypher
"CALL { MATCH (s:Place) WHERE s.name = $b0_s_name_0 RETURN s UNION ALL MATCH (s:Place) WHERE s.name = $b1_s_name_0 RETURN s } WITH s OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d"
iex> params
%{"b0_s_name_0" => "Sydney", "b1_s_name_0" => "Melbourne"}
CREATE (n:L1:L2 {props}) RETURN n
MATCH (n:L1:L2 {props}) DETACH DELETE n
MATCH (n:L1:L2 {props}) WHERE NOT guard1 AND NOT guard2 DETACH DELETE n
guards is a list of {edge_label, direction, dest_label} tuples.
Falls back to delete_nodes/2 when guards is empty.
MATCH (n:Labels {props}) RETURN n
MERGE (n:Label {props}) RETURN n
MATCH (s:L1:L2) OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d
MATCH (s:L1:L2) WHERE id(s) IN $ids OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d.
Used as the final read after in-memory combination orchestration computes the keep-set of node ids.
MATCH (s:L1:L2) WHERE <conditions> OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d
Returns node_read/1 when conditions is empty.
MATCH (n:L1:L2 {props}) OPTIONAL MATCH (n)-[r]-(d) RETURN n, r, d
Like node_read/1 but matches by properties in the MATCH pattern (not a WHERE clause).
MATCH (s:SrcLabel {s_props}) OPTIONAL MATCH (d:DestLabel {d_props}) MERGE (s)-[r:EDGE]->(d) RETURN s, r, d
Relates two nodes, removing existing edges from source AND to destination.
MATCH (s:SrcLabel {s_props}) WITH s
OPTIONAL MATCH (s)-[r0:EDGE]->(d:DestLabel {d_props}) DELETE r0 WITH s
OPTIONAL MATCH (d:DestLabel {d_props}) WITH s, d
OPTIONAL MATCH (s0:SrcLabel)-[r0:EDGE]->(d) WHERE s0 <> s DELETE r0
WITH s, d MERGE (s)-[r:EDGE]->(d) RETURN s, r, d
@spec relate_unrelating_destination( atom() | [atom()], map(), atom(), map(), atom(), atom() ) :: t()
Relates two nodes, first removing any existing edge of the same type pointing to the destination.
MATCH (s:SrcLabel {s_props}) OPTIONAL MATCH (d:DestLabel {d_props})
WITH s, d OPTIONAL MATCH (s0:SrcLabel)-[r0:EDGE]->(d) WHERE s0 <> s
DELETE r0 WITH s, d MERGE (s)-[r:EDGE]->(d) RETURN s, r, d
Relates two nodes, first removing any existing edge of the same type from the source.
MATCH (s:SrcLabel {s_props})
WITH s OPTIONAL MATCH (s)-[r0:EDGE]->(d0:DestLabel)
DELETE r0 WITH s MATCH (d:DestLabel {d_props})
MERGE (s)-[r:EDGE]->(d) RETURN s, r, d
@spec relationship_read( atom() | [atom()], atom(), atom(), atom(), String.t(), atom(), any() ) :: t()
MATCH (s:SrcLabels)-[r:EdgeLabel]-(d:DestLabel) WHERE d.prop <op> $param WITH s MATCH (s)-[r0]-(d0) RETURN s, r0, d0
MATCH (s:SrcLabel {s_props})-[r:EDGE]->(d:DestLabel {d_props}) DELETE r RETURN s, d
MATCH (n:L1:L2 {match_props}) SET n += {set_props} REMOVE n.p1, n.p2 RETURN n
Handles all combinations of empty/non-empty set_props and remove_props.