Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Handling Edges #8

Open
dotdotdotpaul opened this issue Jul 27, 2016 · 3 comments
Open

RFC: Handling Edges #8

dotdotdotpaul opened this issue Jul 27, 2016 · 3 comments

Comments

@dotdotdotpaul
Copy link
Collaborator

The current model of doing get/get_or_create/create/update/delete for Vertex works fine, but you can query for "just a vertex".

Extending that to edges, though, is a problem. Although an edge can be returned by itself, and be represented as an Edge struct (with a type and properties hash), you can't actually query for edges "alone" -- you always have to bound them, at the very least as "()-[r]->()" which means you also can't actually create one without a full "triple" to go with it (unless you really want that edge to be duplicated between all nodes in your graph!)

I added a method "get_path" to help me deal with the question "does this path exist already, based on these finders", but it was a kludge to help get some work done. It feels like we should have a get_or_create function for Edge, but it would have to take more arguments, namely, the vertex matchers that the edge should go between. Ultimately, it would come down to "MATCH (x:Foo {}), (y:Bar {}) MERGE (x)-[r:isA {}]->(y) ON CREATE SET r += { id: '12345' } RETURN r, type(r)" -- but what should the elixir actually look like? Graph.get_or_create(path=%Triple{}, created_edge_props=%{}) ?

Maybe I'm over thinking it, but would love suggestions for how this should work. Should it just use the Triple we already have? or use pattern matching to allow for either a keyword hash that turns into a Triple, or what... Now that we have other people looking at the package and the code, I'm definitely keen to hear what others think.

@mkompanets
Copy link
Contributor

This proposed API for getting/creating/getting_or creating edges comes from thinking that an edge does not really makes sense without it's vertices. It could contain information about itself though, but always inferring things it is connected to.

This is what I had in mind:

#
# get
#
def get(v1, v2) do
  # gets all existing edges
  # Cypher:
  # MATCH (v1)-[edge]->(v2) RETURN edge, type(edge)
end

def get(v1, v2, label) do
  # gets all existing edges with given label
  # Cypher:
  # MATCH (v1)-[edge:label]->(v2) 
  # RETURN edge, type(edge)
end

def get(v1, v2, edge) do
  # gets all existing edges with edge struct that includes attributes.
  # Cypher:
  # MATCH (v1)-[edge:%edge.label {prop1: %edge.prop1}]->(v2) 
  # RETURN edge, type(edge)
end

#
# create
#
def create(v1, v2) do
  # create an edge with no attributes.  Must first make sure that
  # verticies exist though.  The idea is we just want to connect two nodes.
  # Cypher:
  # MATCH (v1)
  # MATCH (v2) 
  # CREATE (v1)-[edge]->(v2) 
  # RETURN edge, type(edge)
end

def create(v1, v2, label) do
  # create an edge with a label.  Again, we must make sure that
  # verticies exist.
  # Cypher:
  # MATCH (v1)
  # MATCH (v2) 
  # CREATE (v1)-[edge:label]->(v2) 
  # RETURN edge, type(edge)
end

def create(v1, v2, edge) do
  # create an edge with an edge struct that includes a label and attributes.
  # Cypher:
  # MATCH (v1)
  # MATCH (v2) 
  # CREATE (v1)-[edge:%edge.label {prop1: %edge.prop1}]->(v2) 
  # RETURN edge, type(edge)
end

def get_or_create(v1, v2) do
  # make sure verticies exist and call MERGE. I don't know if cypher MERGE
  # would assume 'any' edge or specifically look for an empty one.  Should look into this.
  # Cypher:
  # MATCH (v1)
  # MATCH (v2) 
  # MERGE (v1)-[]->(v2) 
  # RETURN edge, type(edge)  
end

def get_or_create(v1, v2, label) do
  # Same as create/3, only use merge instead.
end

def get_or_create(v1, v2, edge) do
  # Same as create/3, only use merge instead.
end

@dotdotdotpaul
Copy link
Collaborator Author

dotdotdotpaul commented Aug 2, 2016

Michael, are you proposing those functions be part of the Edge module, or alternate-arity functions on the GraphDB model? What would the function be to "get all edges leading out of this Vertex" (or conversely, "leading into this Vertex")?

@mkompanets
Copy link
Contributor

I am not sure what the best place for these functions would be. Being part of the Edge module sounds nice, but it would be more important to be consistent with the rest of the API.

get_all_out_edges and get_all_in_edges sound like nice functions to have in the Vertex module. That may lead to some overlap in the code between Vertex and Edge, but that's where I would expect to find them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants