Search code examples
neo4jclient

Ensure unique nodes with neo4jclient


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?


Solution

  • 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.