Created
September 20, 2017 11:01
-
-
Save Fadhil/5f205587305930b310de8549b44a9ec6 to your computer and use it in GitHub Desktop.
Basic Neo4j + Ecto stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# I'm doing something like this to build queries: | |
@spec match(%Query{}, map, string, map) :: %Query{} | |
def match(current_query, res_a, rel, res_b) | |
when is_map(res_a) and is_map(res_b) do | |
query_string = """ | |
MATCH (#{get_node_var(res_a)}:#{node_name(res_a)} {#{attributes_from_struct(res_a)}}) | |
MATCH (#{get_node_var(res_b)}:#{node_name(res_b)} {#{attributes_from_struct(res_b)}}) | |
WITH #{get_node_var(res_a)}, #{get_node_var(res_b)} | |
MATCH (#{get_node_var(res_a)})-[rel:#{rel}]->(#{get_node_var(res_b)}) | |
""" | |
current_query | |
|> append(query_string) | |
end | |
def with(query, node_var) when is_bitstring node_var do | |
query_string = """ | |
WITH #{node_var} | |
""" | |
query | |
|> append(query_string) | |
end | |
def append(query, query_string) do | |
%{query | | |
string: query.string <> " " <> query_string | |
} | |
end | |
def return(current_query, node_var) when is_bitstring node_var do | |
query_string = """ | |
RETURN #{node_var} | |
""" | |
current_query | |
|> append(query_string) | |
end | |
# So that I can do stuff like: | |
iex(10)> query = %Query{} |> Query.match(%User{email: "fadhil.luqman@gmail.com"}, "OWNS", %Organisation{}) |> Query.return(["user", "organisation"]) | |
%Flexcility.Graph.Query{ | |
string: " MATCH (user:User {email: 'fadhil.luqman@gmail.com'})\n MATCH (organisation:Organisation {})\n WITH user, organisation\n MATCH (user)-[rel:OWNS]->(organisation)\n RETURN user, organisation\n" | |
iex(12)> {:ok, [res]} = Graph.run_query(query.string) | |
[debug] [#Port<0.15312>] cypher: "MATCH (user:User {email: 'fadhil.luqman@gmail.com'})\n MATCH (organisation:Organisation {})\n WITH user, organisation\n MATCH (user)-[rel:OWNS]->(organisation)\n RETURN user, organisation" - params: %{} - bolt: [success: %{"fields" => ["user", "organisation"]}, record: [[sig: 78, fields: [419, ["User"], %{"email" => "fadhil.luqman@gmail.com", "id" => 4, "name" => "Fadhil", "password_hash" => "$2b$12$b1.dBvf1tgBzQaiMk0nzxOEe/elzkGuLOOicz2.SyPKP1cHhAuFsi", "uuid" => "02a72bb0-996b-11e7-88a7-964f323b1657"}]], [sig: 78, fields: [412, ["Organisation"], %{"id" => 2, "location" => "Wilayah Persekutuan", "name" => "JKR", "subdomain" => "jkr", "uuid" => "bdcb6e12-962d-11e7-88a7-964f323b1657"}]]], success: %{"type" => "r"}] | |
{:ok, | |
[%{"organisation" => %Bolt.Sips.Types.Node{id: 412, labels: ["Organisation"], | |
properties: %{"id" => 2, "location" => "Wilayah Persekutuan", | |
"name" => "JKR", "subdomain" => "jkr", | |
"uuid" => "bdcb6e12-962d-11e7-88a7-964f323b1657"}}, | |
"user" => %Bolt.Sips.Types.Node{id: 419, labels: ["User"], | |
properties: %{"email" => "fadhil.luqman@gmail.com", "id" => 4, | |
"name" => "Fadhil", | |
"password_hash" => "$2b$12$b1.dBvf1tgBzQaiMk0nzxOEe/elzkGuLOOicz2.SyPKP1cHhAuFsi", | |
"uuid" => "02a72bb0-996b-11e7-88a7-964f323b1657"}}}]} | |
# I've also got a Utils.get_struct function that modifies this into Ecto structs like so (using res from above): | |
iex(22)> [User, Organisation] |> Enum.map(&(Utils.get_struct(res, &1))) | |
[%Flexcility.Accounts.User{__meta__: #Ecto.Schema.Metadata<:built, "User">, | |
email: "fadhil.luqman@gmail.com", id: 4, image: nil, name: "Fadhil", | |
organisations: #Ecto.Association.NotLoaded<association :organisations is not loaded>, | |
password_hash: "$2b$12$b1.dBvf1tgBzQaiMk0nzxOEe/elzkGuLOOicz2.SyPKP1cHhAuFsi"}, | |
%Flexcility.Accounts.Organisation{__meta__: #Ecto.Schema.Metadata<:built, "Organisation">, | |
description: nil, id: 2, location: "Wilayah Persekutuan", name: "JKR", | |
sites: #Ecto.Association.NotLoaded<association :sites is not loaded>, | |
subdomain: "jkr"}] | |
# Where Utils is basically: | |
def get_struct(map, resource) do | |
get_changeset(map, resource) | |
|> Changeset.apply_changes() | |
end | |
def get_changeset(map, resource) do | |
props = map | |
|> get_properties(resource) | |
resource.__struct__ | |
|> Changeset.cast(props, resource.__schema__(:fields)) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment