Creating human-friendly incremented unique IDs

I'm using Neo4J as the backend to an application that is effectively a content management platform. Users can upload assets (such as PDFs) and manage the relationships between assets.

To aid the identification of assets, we create a unique ID and want them to be human friendly. For example, documents might have use "DO-003456". The main reason for these IDs is that document title aren't unique and we could have alternate titles in other languages.

I'm familiar with the internal ID() concept and the cons that go with using those. I'm also familiar with the true UUID approach using apoc functions or something similar. The problem with the UUID approach is the values aren't really human friendly. Imagine the frustration and human errors involved in reading off a 36 bit hexadecimal number when asking a coworker to open a particular document.

The approach I use currently is a basic incrementor with a prefix. When creating a new entry the process is basically..

  1. Get the current max integer portion, after removing the prefix portion.
    MATCH (d:Doc)
    RETURN MAX(toInteger(substring(d.GUID,2))) as GUID
    (the assumption here is that "Doc" labels all use the same GUID prefix)

  2. Create a new entry using prefix + (GUID+1)

This approach works, but could run into a race condition in the rare event of simultaneous inserts.

Any suggestions on alternate approaches to managing the creations of IDs that are in a form like "Prefix-integer".


Here is a suggestion:

Add language to your GUID like:

langiuage-DO-003456 or DO-language-003456

Hi @kurt_slater ,

For a client-side approach, you could look at something like the nanoid library,
which is available in many programming languages and let's you generate unique
identifiers using an alphabet and length of your choosing.

If the approach is useful, then you could wrap it into a cypher procedure and use it on the DBMS-side.

Check out: GitHub - ai/nanoid: A tiny (130 bytes), secure, URL-friendly, unique string ID generator for JavaScript


And for another solution, perhaps you could achieve integer auto incrementing using the apoc.atomic functions?

I found discovered this page which discusses the same general topic.

The approach near the bottom of the page seems sound. The general idea is to use a single node to maintain an incremented integer that can be used when creating new nodes across the entire graph.

MERGE (id:GlobalUniqueId)
ON CREATE SET id.count = 1
ON MATCH SET id.count = id.count + 1
WITH id.count AS newID
CREATE (b:Book{uniqueID:'BO-'+newID, title:'The book of things'})

Any thoughts on this approach? I'm not entirely convinced it avoids race conditions.