4

Is it possible in Neo4j or SDN4 to create/emulate something similar to a PostgreSQL sequence database object?

I need this thread safe functionality in order to be able to ask it for next, unique Long value. I'm going to use this value as a surrogate key for my entities.

UPDATED

I don't want to go with UUID because I have to expose these IDs within my web application url parameters and in case of UUID my urls look awful. I want to go with a plain Long values for IDs like StackOverflow does, for example:

stackoverflow.com/questions/42228501/neo4j-sdn-4-emulate-sequence-objectnot-uuid
alexanoid
  • 24,051
  • 54
  • 210
  • 410

4 Answers4

2

This can be done with user procedures and functions. As an example:

package sequence;

import org.neo4j.procedure.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Next {
    private static AtomicInteger sequence = new AtomicInteger(0);

    @UserFunction
    public synchronized Number next() {
        return sequence.incrementAndGet();
    }
}

The problem of this example is that when the server is restarted the counter will be set to zero.

So it is necessary to keep the last value of the counter. This can be done using these examples:

https://maxdemarzi.com/2015/03/25/triggers-in-neo4j/

https://github.com/neo4j-contrib/neo4j-apoc-procedures/blob/master/src/main/java/apoc/trigger/Trigger.java

stdob--
  • 28,222
  • 5
  • 58
  • 73
  • This doesn't really add any extra benefit if used between startups. If it's only used while the server is running, then the internal Neo4j ID would be better anyway. – digx1 Feb 15 '17 at 12:06
  • @digx1 Neo4j id is not increment sequence. – stdob-- Feb 15 '17 at 12:25
  • 1
    FWIW the Neo4j id is for the most part, allocated sequentially. The point is this solution is not very useful for someone trying to make a sequence per label across restarts. This solution either needs a namespace to replicate what a postgres sequence does or someone should actually just build the APOC procedure: https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/225 that would do this. – digx1 Feb 15 '17 at 12:58
1

No. As far as I'm aware there isn't any similar functionality to sequences or auto increment identifiers in Neo4j. This question has also been asked a few times in the past.

The APOC project might be worth checking out for this though. There seems to be a request to add it.

Community
  • 1
  • 1
digx1
  • 1,100
  • 5
  • 9
1

If your main interest is in having a way to generate unique IDs, and you do not care if the unique IDs are strings, then you should consider using the APOC facilities for generating UUIDs.

There is an APOC function that generates a UUID, apoc.create.uuid. In older versions of APOC, this is a procedure that must be invoked using the CALL syntax. For example, to create and return a single Foo node with a new UUID:

CREATE (f:Foo {uuid: apoc.create.uuid()})
RETURN f;

There is also an APOC procedure, apoc.create.uuids(count), that generates a specified number of UUIDs. For example, to create and return 5 Foo nodes with new UUIDs:

CALL apoc.create.uuids(5) YIELD uuid
CREATE (f:Foo {uuid: uuid})
RETURN f;
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • Thanks, but I don't want to go with UUID because I have to expose these IDs within my web application urls parameters and in case of UUID my urls looks awful. I want to go with a plain Long values for IDs. – alexanoid Feb 15 '17 at 12:25
0

The most simplest way in Neo4j is to disable ids reuse and use node Graph ID like sequencer.

https://neo4j.com/docs/operations-manual/current/reference/configuration-settings/

Table A.83. dbms.ids.reuse.types.override

Description: Specified names of id types (comma separated) that should be reused. Currently only 'node' and 'relationship' types are supported.

Valid values: dbms.ids.reuse.types.override is a list separated by "," where items are one of NODE, RELATIONSHIP

Default value: [RELATIONSHIP, NODE]
alexanoid
  • 24,051
  • 54
  • 210
  • 410