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 hidden or 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: "[email protected]"}, "OWNS", %Organisation{}) |> Query.return(["user", "organisation"]) | |
| %Flexcility.Graph.Query{ | |
| string: " MATCH (user:User {email: '[email protected]'})\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: '[email protected]'})\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" => "[email protected]", "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" => "[email protected]", "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: "[email protected]", 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