apoc.hashing.fingerprinting

Function APOC Core

calculate a checksum (md5) over a node or a relationship. This deals gracefully with array properties. Two identical entities do share the same hash. MD5 is a weak hashing algorithm which is unsuitable for cryptographic use-cases.

Signature

apoc.hashing.fingerprinting(some object :: ANY?, conf = {} :: MAP?) :: (STRING?)

Input parameters

Name Type Default

some object

ANY?

null

conf

MAP?

{}

Config parameters

The procedure support the following config parameters:

Table 1. Config parameters
name type default description

digestAlgorithm

String

"MD5"

The algorithm used to compute the fingerprint. Supported values are: MD5, SHA-1, SHA-256

strategy

String

"LAZY"

Property loading strategy. Supported values are:

  • LAZY - does not include properties

  • EAGER - uses all properties

nodeAllowMap

Map<String, List<String>>

{}

Properties to include per node label

nodeDisallowMap

Map<String, List<String>>

[]

Properties to exclude per node label

relAllowMap

Map<String, List<String>>

{}

Properties to include per relationship type

relDisallowMap

Map<String, List<String>>

[]

Properties to exclude per relationship type

mapAllowList

List<String>

[]

Map properties to include

mapDisallowList

List<String>

[]

Map properties to exclude

allNodesAllowList

List<String>

[]

Node properties to include

allNodesDisallowList

List<String>

[]

Node properties to exclude

allRelsAllowList

List<String>

[]

Relationship properties to include

allRelsDisallowList

List<String>

[]

Relationship properties to exclude

Usage Examples

The examples in this section are based on the following sample graph:

MERGE (joe:Person {name: "Joe"})
MERGE (ryan:Person {name: "Ryan"})
MERGE (ryan)-[:FOLLOWS {since: datetime("2020-11-04")}]->(joe);

The following generates the fingerprint for Ryan:

MATCH (person:Person {name: "Ryan"})
RETURN apoc.hashing.fingerprinting(person) AS output;
Table 2. Results
output

"D41D8CD98F00B204E9800998ECF8427E"

The following generates the fingerprint for Ryan, using the EAGER strategy, which includes node properties:

MATCH (person:Person {name: "Ryan"})
RETURN apoc.hashing.fingerprinting(person, {
  strategy: "EAGER"
}) AS output;
Table 3. Results
output

"81C99DD6C9382C4E01A1873F9E818CE0"

The following generates the fingerprint for Ryan, excluding the name property:

MATCH (person:Person {name: "Ryan"})
RETURN apoc.hashing.fingerprinting(person, {
  allNodesDisallowList: ["name"]
}) AS output;
Table 4. Results
output

"D41D8CD98F00B204E9800998ECF8427E"

The following generates the fingerprint for Ryan, using the SHA-256 algorithm:

MATCH (person:Person {name: "Ryan"})
RETURN apoc.hashing.fingerprinting(person, {
  digestAlgorithm: "SHA-256"
}) AS output;
Table 5. Results
output

"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"

If we want less control over the generation of the fingerprint, see apoc.hashing.fingerprint.