Joel Stevick
Joel Stevick

Reputation: 2028

How do I find a Neo4j node using an indexed property, across all types?

I am storing a unique identifier for every node using a property named "uid". This property is maintained across all types. However, GraphDatabase.findNode(...) requires that you pass in a non-null value for "label". So, how do I do a cross-type find?

The only thing that I can think of is to execute a cypher query to do this.

Upvotes: 0

Views: 156

Answers (1)

William Lyon
William Lyon

Reputation: 8546

I see two options here:

1) Create a new "super" label that all nodes have and create your index on this label.

2) Use a manual index

1. "Super" label

Since nodes can have multiple labels you can create a new label that acts a super label that all nodes have. Then create a schema index on the uid property on that label and query it.

For example, let's say you currently have the node labels User and Customer and you want to do an indexed lookup for the node where the uid property is 123 across both node labels. Create a new label Person on all nodes that have either User or Customer label:

MATCH (a)
WHERE any(x in labels(a) WHERE x IN ["User", "Customer"])
SET a:Person;

Now create an index on :Person(uid):

CREATE INDEX ON :Person(uid);

Since this is a unique identifier it should really have a uniqueness constraint (which will create an index):

CREATE CONSTRAINT ON (p:Person) ASSERT p.uid IS UNIQUE;

And search this new schema index:

MATCH (p:Person {uid: "123"})
RETURN p

or since you are the Java API:

Node person = graphdb.findNode("Person", "uid", "123")

2. Manual Index

Since you are using the Java API you also have the option of creating a manual index:

// Create index
IndexManager index = graphdb.index();
Index<Node> people = index.forNodes("people");

// Add nodes to index
Node user1 = graphdb.createNode();
user1.setProperty("uid", "123");

// Search index
IndexHits<Node> hits = people.get("uid", "123");
Node user123 = hits.getSingle();

Upvotes: 4

Related Questions