1
votes

I have two types of nodes (node1) and (node2) with about 100,000 records in each. I have one type of relationship [:TYPE1] between those two nodes on only 100 rows of (a)

If I profile: MATCH (a:node1)-[:TYPE1]->(b:node2) RETURN a.field1, b.field2

it says it does a NodeByLabelScan with 80,000+ db hits, then uses the relationship to filter down to the 100 rows I want with many more db hits. The query does return the rows I want, but how can I get the neo4j analyzer to look at [:TYPE1] as the lowest cardinality to start the execution path?

Using Neo4j V 3.1.2 on Windows 10

Thanks

2
I may be overlooking something, but I looked into that but the hints force index use on nodes or scans of nodes. I need to force the use of a relationship type as the preferable limiting factor. - AndyP1970

2 Answers

4
votes

As InverseFalcon said Neo4j's schema indexes don't apply to relationships. And the method he proposed works. There is another option: use node labels.

For example, add nodes and relationship:

CREATE (n1:node1)
CREATE (n2:node2)
CREATE (n1)-[r:TYPE1]->(n2)
SET n1:REL_OUT_TYPE1,
    n2:REL_IN_TYPE1
RETURN n1, n2, r 

And match:

MATCH (n1:node1:REL_OUT_TYPE1)-[:TYPE1]->(n2:node2:REL_IN_TYPE1)
RETURN n1, n2
3
votes

Neo4j's schema indexes don't apply to relationships, so you'll need to use the legacy indexes instead. APOC Procedures has support for these, and will be the easiest way to lookup relationships by type. Definitely install APOC when you get the chance to take advantage of this.

However, APOC's approach for these indexes is by type and a property, not type alone. This may require you to add a placeholder property on all relationships of that type so they can be added to the manual index and queried later.

Something like this:

MATCH (:node1)-[r:TYPE1]->(:node2)
SET r.indexed = true
CALL apoc.index.addRelationship(r,['indexed'])
RETURN DISTINCT 1

Once that's done, you can use APOC to lookup relationships via the relationship index:

CALL apoc.index.relationships('TYPE1','indexed:true') YIELD rel
WITH startNode(rel) as a, endNode(rel) as b
RETURN a.field1, b.field2

You can also use *:* in the above query for the property lookup to save a few keystrokes.

Note that these indexes are manual, not automatic, so you'll need to apply this to any new :TYPE1 relationships you want to add.

Support is being implemented for automatically updating manual indexes in APOC, a few issues are being ironed out still, and I don't think the instructions for this have been added to the documentation yet.