Packages

A RedisGraph client implementation.

Current section

Files

Jump to
redisgraph lib redis_graph edge.ex
Raw

lib/redis_graph/edge.ex

defmodule RedisGraph.Edge do
@moduledoc """
An Edge component relating two Nodes in a Graph.
Edges must have a source node and destination node, describing a relationship
between two entities in a Graph. The nodes must exist in the Graph in order
for the edge to be added.
Edges must have a relation which identifies the type of relationship being
described between entities
Edges, like Nodes, may also have properties, a map of values which describe
attributes of the relationship between the associated Nodes.
"""
alias RedisGraph.Util
@type t() :: %__MODULE__{
id: integer(),
src_node: Node.t() | number(),
dest_node: Node.t() | number(),
relation: String.t(),
properties: %{optional(String.t()) => any()}
}
@enforce_keys [:src_node, :dest_node, :relation]
defstruct [:id, :src_node, :dest_node, :relation, properties: %{}]
@doc """
Create a new Edge from a map.
## Example
edge = Edge.new(%{
src_node: john,
dest_node: japan,
relation: "visited"
})
"""
@spec new(map()) :: t()
def new(map) do
struct(__MODULE__, map)
end
@doc "Convert an edge's properties to a query-appropriate string."
@spec properties_to_string(t()) :: String.t()
def properties_to_string(edge) do
inner =
Map.keys(edge.properties)
|> Enum.map(fn key -> "#{key}:#{Util.quote_string(edge.properties[key])}" end)
|> Enum.join(",")
if String.length(inner) > 0 do
"{" <> inner <> "}"
else
""
end
end
@doc "Convert an edge to a query-appropriate string."
@spec to_query_string(t()) :: String.t()
def to_query_string(edge) do
src_node_string = "(" <> edge.src_node.alias <> ")"
edge_string =
case edge.relation do
"" -> "-[" <> properties_to_string(edge) <> "]->"
nil -> "-[" <> properties_to_string(edge) <> "]->"
other -> "-[:" <> other <> properties_to_string(edge) <> "]->"
end
dest_node_string = "(" <> edge.dest_node.alias <> ")"
src_node_string <> edge_string <> dest_node_string
end
@doc """
Compare two edges with respect to equality.
Comparison logic:
* If the ids differ, returns ``false``
* If the source nodes differ, returns ``false``
* If the destination nodes differ, returns ``false``
* If the relations differ, returns ``false``
* If the properties differ, returns ``false``
* Otherwise returns `true`
"""
@spec compare(t(), t()) :: boolean()
def compare(left, right) do
cond do
left.id != right.id -> false
left.src_node != right.src_node -> false
left.dest_node != right.dest_node -> false
left.relation != right.relation -> false
map_size(left.properties) != map_size(right.properties) -> false
not Map.equal?(left.properties, right.properties) -> false
true -> true
end
end
end