AshNeo4j.Cypher.Query (AshNeo4j v0.5.1)

Copy Markdown View Source

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?}

t()

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.

CREATE (n:L1:L2 {props}) RETURN n

MATCH (n:Label {props}) DETACH DELETE n

MATCH (n:Label {props}) WHERE NOT guard1 AND NOT guard2 DETACH DELETE n

MATCH (n:Labels {props}) RETURN n

MERGE (n:Label {props}) RETURN n

MATCH (s:Label) OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d

MATCH (s:Label) WHERE <conditions> OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d

MATCH (n:Label {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:SrcLabel)-[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:Label {match_props}) SET n += {set_props} REMOVE n.p1, n.p2 RETURN n

Types

clause()

condition()

@type condition() :: {String.t(), atom(), any(), boolean()}

A single property filter condition for node_read_filtered/2: {property, operator_atom, value, case_insensitive?}

t()

@type t() :: %AshNeo4j.Cypher.Query{clauses: [clause()], params: map()}

Functions

add_limit(query, n)

@spec add_limit(t(), pos_integer() | nil) :: t()

Appends a LIMIT clause. No-op when n is nil.

add_order_by(query, terms)

@spec add_order_by(t(), [{atom() | String.t(), :asc | :desc}]) :: t()

Appends an ORDER BY clause. No-op when terms is empty.

add_skip(query, n)

@spec add_skip(t(), non_neg_integer() | nil) :: t()

Appends a SKIP clause. No-op when n is nil or 0.

aggregate_per_record(source_label, pk_field, ids, path_segments, kind, field, name, uniq? \\ false)

@spec aggregate_per_record(
  atom(),
  atom(),
  [any()],
  [{atom(), atom(), atom()}],
  atom(),
  atom() | nil,
  atom(),
  boolean()
) :: t()

Per-record aggregate — returns one row per source node with the aggregate value.

MATCH (s:Label) 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.

aggregate_total(source_label, pk_field, ids, path_segments, kind, field, name, uniq? \\ false)

@spec aggregate_total(
  atom(),
  atom(),
  [any()],
  [{atom(), atom(), atom()}],
  atom(),
  atom() | nil,
  atom(),
  boolean()
) :: t()

Total aggregate — returns a single row with the aggregate value across all source nodes.

MATCH (s:Label) WHERE s.pk IN $agg_ids OPTIONAL MATCH (s)<path>(d) RETURN agg_fn AS name

create_node(labels, properties)

@spec create_node(atom() | [atom()], map()) :: t()

CREATE (n:L1:L2 {props}) RETURN n

delete_nodes(label, properties \\ %{})

@spec delete_nodes(atom(), map()) :: t()

MATCH (n:Label {props}) DETACH DELETE n

delete_nodes_guarded(label, properties, guards)

@spec delete_nodes_guarded(atom(), map(), list()) :: t()

MATCH (n:Label {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_nodes(labels, properties \\ %{})

@spec match_nodes(atom() | [atom()], map()) :: t()

MATCH (n:Labels {props}) RETURN n

merge_node(label, properties)

@spec merge_node(atom(), map()) :: t()

MERGE (n:Label {props}) RETURN n

node_read(label)

@spec node_read(atom()) :: t()

MATCH (s:Label) OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d

node_read_filtered(label, conditions)

@spec node_read_filtered(atom(), [condition()]) :: t()

MATCH (s:Label) WHERE <conditions> OPTIONAL MATCH (s)-[r]-(d) RETURN s, r, d

Returns node_read/1 when conditions is empty.

node_read_with_properties(label, properties)

@spec node_read_with_properties(atom(), map()) :: t()

MATCH (n:Label {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).

relate(src_label, src_props, dest_label, dest_props, edge_label, direction)

@spec relate(atom() | [atom()], map(), atom() | [atom()], map(), atom(), atom()) ::
  t()

MATCH (s:SrcLabel {s_props}) OPTIONAL MATCH (d:DestLabel {d_props}) MERGE (s)-[r:EDGE]->(d) RETURN s, r, d

relate_unrelating_both(src_label, src_props, dest_label, dest_props, edge_label, direction)

@spec relate_unrelating_both(atom(), map(), atom(), map(), atom(), atom()) :: t()

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

relate_unrelating_destination(src_label, src_props, dest_label, dest_props, edge_label, direction)

@spec relate_unrelating_destination(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

relate_unrelating_source(src_label, src_props, dest_label, dest_props, edge_label, direction)

@spec relate_unrelating_source(atom(), map(), atom(), map(), atom(), atom()) :: t()

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

relationship_read(src_label, edge_label, direction, dest_label, dest_property, operator, value)

@spec relationship_read(atom(), atom(), atom(), atom(), String.t(), atom(), any()) ::
  t()

MATCH (s:SrcLabel)-[r:EdgeLabel]-(d:DestLabel) WHERE d.prop <op> $param WITH s MATCH (s)-[r0]-(d0) RETURN s, r0, d0

unrelate(src_label, src_props, dest_label, dest_props, edge_label, direction)

@spec unrelate(atom(), map(), atom(), map(), atom(), atom()) :: t()

MATCH (s:SrcLabel {s_props})-[r:EDGE]->(d:DestLabel {d_props}) DELETE r RETURN s, d

update_node(label, match_props, set_props, remove_props \\ [])

@spec update_node(atom(), map(), map(), [atom()]) :: t()

MATCH (n:Label {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.