4
votes

Using Neo4j 2.1.4 and SDN 3.2.0.RELEASE

I have a graph that connects nodes with relationships that have a UUID associated with them. External systems use the UUID as a means to identify the source and target of the relationship. Within Spring Data Neo4j (SDN) we have a @RelationshipEntity(type=”LINKED_TO”) class with a @StartNode, @EndNode and a String uuid field. The uuid field is @Indexed and the resulting schema definition in Neo4j shows up as

neo4j-sh (?)$ SCHEMA
==> Indexes
...
==>   ON :Link(uuid) ONLINE
...

However, running a cypher query against the data, e.g.

MATCH ()-[r:LINKED_TO]->() WHERE uuid=’XXXXXX’ RETURN r;

does a full scan of the database and takes a long time

If I try to use the index by running

MATCH ()-[r:LINKED_TO]->() USING INDEX r:Link(uuid) WHERE uuid=’XXXXXX’ RETURN r;

I get

SyntaxException: Type mismatch: expected Node but was Relationship.

As I understand it, Relationships are supposed to be first class citizens in Neo4j, but I can’t see how to utilize the index on the relationship to prevent the graph equivalent of a table scan on the database to locate the relationship.

I know there are posts like How to use relationship index in Cypher which ask similar things, but this Link is the relationship between the two nodes. If I converted the Link to a Node, we would be creating a Node to represent a Relationship which seems wrong when we are working in a graph database - I'd end up with ()-[:xxx]->(:Link)-[:xxx]->() to represent one relationship. It would make the model messy purely due to the fact that the Link couldn't be represented as a relationship.

The Link has got a unique, shared key attached to it that I want to use. The Schema output suggests that the index is there for that field - I just can't use it.

Does anyone have any suggestions?

Many thanks,

Dave

1
I don't get it. Is your uuid a node property or a relationship property? According to your schema, you have an index on :Link(uuid), where Link is a label which can only exist on nodes. But in your second query, you're putting the label next to a relationship (which also explains your SyntaxException).Jan Van den bosch
The uuid is a relationship property. I think there is some confusion as adding an @Indexed(unique=true) String uuid; onto the @RelationshipEntity(type="LINKED_TO") public class Link results in SDN executing create constraint on (n:Link) assert n.uuid is unique which, as you say, is actually creating a constraint on a Node with label Link - hence why it doesn't work. I think that's a bug in SDN - it shouldn't allow @Indexed on a @RelationshipEntity. But there's still the whole question about how to index the property on the Link relationship.Dave Hallam

1 Answers

1
votes

Schema indexes are only available for nodes. The only way to index relationships is using legacy indexes or autoindexes. Legacy indexes need to be used explicitly in the START clause:

START r=relationship:my_index_name(uuid=<myuuid>)
RETURN r

I'm not sure how this can be used in conjunction with SDN.

side note: requiring relationship index is almost always a indication of doing something wrong in your graph data model. Everything being a thing or having an identity in your domain should be a node. So if a relationship requires a uuid, maybe the relationship refers to a thing and therefore should be converted into a node having a inbound relationship to the previous start node and a outbound relationship to the previous end node.