3

I'm looking for a way to generate unique identifiers for all my nodes/relationships in Neo4j, based on an incrementing counter (not big long uuids).

The internal ids maintained by the Neo4j engine are known not to be reliable as outside references.

A solution that comes close is the code proposed in this question, but it doesn't work when a single CREATE clause creates multiple new nodes:

// get unique id
MERGE (id:UniqueId{name:'Person'})
ON CREATE SET id.count = 1
ON MATCH SET id.count = id.count + 1
WITH id.count AS uid
// create a new node attached to every existing :something node
MATCH (n:something)
CREATE (:somethingRelated {id:uid}) -[:rel]-> (n)

When there are multiple (n:something), every newly created (:somethingRelated) will share the same id. Is there some way around this, using only Cypher?

Community
  • 1
  • 1
mhelvens
  • 4,225
  • 4
  • 31
  • 55

2 Answers2

2

Try this to allocate a block of ids:

// collect nodes to connect
MATCH (n:Crew) WITH collect(n) AS nodes
MERGE (id:UniqueId { name:'Person' })
// reserve id-range
SET id.count = coalesce(id.count,0)+ size(nodes)
WITH nodes, id.count - size(nodes) AS base 
// for each index
UNWIND range(0,size(nodes)-1) AS idx
// get node, compute id
WITH nodes[idx] AS n, base +idx AS id
CREATE (:SomethingRelated { uid:id })-[:rel]->(n)
Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • This looks interesting. I'm going to have to look up some of those functions you're using (), but from my first read-through, this may very well be what we're looking for. Thanks! – mhelvens Aug 19 '15 at 09:45
  • Sorry for accepting this answer so late. My attentions were drawn elsewhere for the last month or so. But your code is awesome! – mhelvens Sep 29 '15 at 11:15
1

From my point of view it's not possible to do that in Cypher.

I suggest you to write Java Extension for that, because your approach with Cypher would not work in concurrent environment. You are not able to secure uniqueness.

Could you please tell us more about your use case and why you don't to use UUID? - https://github.com/graphaware/neo4j-uuid

Based on your comment below I suggest to create ID's in your application.

MicTech
  • 42,457
  • 14
  • 62
  • 79
  • It's an app in Node.js. There are two reasons we'd prefer not using UUIDs: **(1)** We often communicate verbally about nodes in the database, and giving a number is much easier than giving a 16-char string. **(2)** We'd have to use a Neo4j plugin (otherwise we'll run into the same problem), and that makes it that much more troublesome for others to install our Node.js app. – mhelvens Aug 17 '15 at 11:14