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

Neo4J MERGE support #10

Open
sheerun opened this issue Dec 18, 2013 · 10 comments
Open

Neo4J MERGE support #10

sheerun opened this issue Dec 18, 2013 · 10 comments

Comments

@sheerun
Copy link

sheerun commented Dec 18, 2013

MERGE is introduced in Neo4j 2. Will this gem support it?

@andreasronge
Copy link
Owner

why not,
How would you like the DSL to look like for merge ?

@sheerun
Copy link
Author

sheerun commented Dec 19, 2013

For nodes:

Neo4j.merge(id: 12).on_create(name: 'John').on_match(updated_at: 'timestamp()')

For relationships:

Neo4j.merge_path { |n| n > rel(:friends) > node(2) }

Btw. documentation for Neo4j.create is in wrong place (With):
https://github.com/andreasronge/neo4j/wiki/Neo4j%3A%3ACypher-With

@OpenCoderX
Copy link

How would I pass a label?

@sheerun
Copy link
Author

sheerun commented Feb 5, 2014

The same way as create

Neo4j.merge({ id: 12 }, :foobar)

@andreasronge
Copy link
Owner

Hmm, how about something like this:

merge{node.create({ id: 12 }, :foobar)}

Then a DSL for merge on multiple relationship would be similar:

Example:

merge do
   match({name:'Oliver Stone'}, :Person) >  "movie:Movie" > match({name:'Rob Reiner'}, :Person)
end
ret(:movie)

generates cypher:

MATCH (oliver:Person { name:'Oliver Stone' }),(reiner:Person { name:'Rob Reiner' })
MERGE (oliver)-[:DIRECTED]->(movie:Movie)<-[:ACTED_IN]-(reiner)
RETURN movie

@sheerun
Copy link
Author

sheerun commented Feb 5, 2014

I don't think matches should be nested in merge, because they are in no way local to it. On the other hand on_create and on_match make sense only in context of merge.

Probably following makes more sense:

oliver = match({name:'Oliver Stone'}, :Person)
rob = match({name:'Rob Reiner'}, :Person)
merge(oliver >  "movie:Movie" > rob)

And for nodes:

merge({name:'Oliver Stone'}, :Person) do
  on_match(age: '12')
  on_create(created_at: 'timestamp()')
end

which is the same as:

merge(oliver >  "movie:Movie" > rob).on_create(...).on_match(...)
merge({name:'Oliver Stone'}, :Person).on_create(...).on_match(...)

So generally merge could accept either node or relationship to match, and the on_match and on_create could be defined in block or chained syntax.

@sheerun
Copy link
Author

sheerun commented Feb 5, 2014

Even better:

match({name:'Oliver Stone'}, :Person).as(:oliver)
match({name:'Rob Reiner'}, :Person).as(:rob)
merge(:oliver > "movie:Movie" > :rob)
ret(:movie)

@andreasronge
Copy link
Owner

That is actually the same as

merge do
   match({name:'Oliver Stone'}, :Person) >  "movie:Movie" > match({name:'Rob Reiner'}, :Person)
end
ret(:movie)

except that the names of the nodes (oliver and rob is generated for you).
So if we implement the syntax above then it is also possible to express it as you suggested

@sheerun
Copy link
Author

sheerun commented Feb 5, 2014

In your case marge expects block it's yielding to return matched relation.

I think it makes more sense to accept this relation as argument. For example it's rather unclear that in example below second match is passed to merge while first match is free-standing.

merge do
   some_guy = match({name:'Rob Reiner'}, :Person)
   match(some_guy > ":friend_of" > :person)
   match({name:'Oliver Stone'}, :Person) > "movie:Movie" > :person
end

When using nested match, you cannot support multiple matches anyway, so what's the advantage? I'm not sure about this.

@sheerun
Copy link
Author

sheerun commented Feb 5, 2014

I fixed syntax, but probably it's messed up anyway. I'm no expert in neo4j-cypher.

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

3 participants