4

Is there a way to ensure uniqueness when creating a node with neo4jclient?

This link transactions shows how to do it using java and transactions, but I don't see any transaction support in neo4jclient. I was able to do it using an explicit Cypher string query something like this:

"start n=node:node_auto_index(name={id}) 
 with count(*) as c 
 where c=0 
 create x={name:{id}} 
 return c"

But this is obviously a hack. Is there a better way?

Alex Kilpatrick
  • 411
  • 1
  • 4
  • 16

1 Answers1

2

Transaction support will come with Neo4j 2.0 and a later version of Neo4jClient. This issue is tracking the work: https://bitbucket.org/Readify/neo4jclient/issue/91/support-cypher-transactions-integrated

That doesn't give you uniqueness though...

Neo4j doesn't have unique indexes are anything to auto-enforce this idea. (I expect we'll see this with Neo4j 2.0 labels in the future, but not yet.)

You need to either a) know that what you're creating is unique, or b) check first.

You seem to be taking the B route.

Transactions allow you to do the check then the create within a single transactional action, but still multiple calls over the wire.

The Cypher text that you've written out is actually preferred: you do the check and create in a single statement. I'm intrigued to know why you think this is a hack.

You can execute this statement via Neo4jClient with something like:

var id = 123;
graphClient.Cypher
    .Start(new { n = Node.ByIndexLookup("node_auto_index", "name", id)})
    .With("count(*) as c")
    .Where("c=0")
    .Create("x={0}", new MyType { name = id })
    .Return<Node<MyType>>("c")

Some of the With and Where statements would be nice if they were cleaner, but it's functional for now.

There's also Cypher's CREATE UNIQUE clause which might cover your scenario too.

Tatham Oddie
  • 4,290
  • 19
  • 31
  • Thanks, Tatham. In my scenario, I can't know that the nodes are unique when I create them, so I have to check first. I tried CREATE UNIQUE, but it does require you to have the nodes and connections. In my case, I had to create a unique node first. It seemed like a hack because I was sending raw Cypher across the wire, which you strongly recommend against. :-) – Alex Kilpatrick May 14 '13 at 02:45
  • I recommend against using ExecuteRawCypherQuery. Using IGraphClient.Cypher to do the with, where and create is fine. – Tatham Oddie May 14 '13 at 03:56
  • What is the advantage of doing it this way? It seems like almost all the arguments are raw text strings anyway. What is gained by passing 4-5 text strings over one text string? – Alex Kilpatrick May 15 '13 at 16:30
  • It's mostly about correct use of params, both for security and performance. In time, we're working to improve the Where method as well. – Tatham Oddie May 15 '13 at 22:47