i have a problem with neo4j. I don't know if problem is my query or something else.
Intro
I have to build an application that store bus/train routes. This is my schema:
Nodes:
Important Relationships:
NEXT relationships contains those properties:
Problem
My query is:
MATCH (s1:Stop {id: {departureStopId}}), (s2:Stop {id: {arrivalStopId}})
OPTIONAL MATCH (s1)-[nexts:NEXT*]->(s2)
WHERE ALL(i in nexts WHERE toInt(i.dayOfWeek) = {dayOfWeek} AND toInt(i.startHour) >= {hour})
RETURN nexts
LIMIT 10
For example: I wanna found all nexts relationships where dayOfWeek is Sunday (0) and property startHour > 11
After that I usually parse and validate final object on my nodejs backend.
This works when i was at the start.. with 1k relationships.. Now i have 10k relationships and my query have a TIMEOUT problem or queries are solved in 30s.. too much time... I have no idea how to solve this. I use neo4j with docker and i tried to read settings docs but i have no idea how Java works.
Can you help me guys?
UPDATE
Thank you all guys! For now i solved with "allShortestPaths" but I think i will rename all relationships (like Michael Hunger said).
Have you tried:
MATCH p=allShortestPaths((s1:Stop {id: {departureStopId}})-[:NEXT*]-> (s2:Stop {id: {arrivalStopId}}) )
WHERE ALL(i in RELS(p) WHERE toInt(i.dayOfWeek) = {dayOfWeek} AND toInt(i.startHour) >= {hour})
RETURN rels(p) as nexts
LIMIT 10
This should use the fast shortest path algorithm because:
Planning shortest paths in Cypher can lead to different query plans depending on the predicates that need to be evaluated. Internally, Neo4j will use a fast bidirectional breadth-first search algorithm if the predicates can be evaluated whilst searching for the path.
See https://neo4j.com/docs/developer-manual/current/cypher/execution-plans/shortestpath-planning/#_shortest_path_with_fast_algorithm for more details.
Can you share your profile.
I presume you have a constraint on :Stop(id)
I would use shortest path or dijkstra with costs instead of optional match. OPTIONAL MATCH will try to find ALL of such paths which are hundreds of millions and filter them as they go.
And it might make sense to group your NEXT relationships by day of week, .e.g :NEXT_MO, :NEXT_THU so you only look at 1/7 th of the data.
It's not settings; it's the fact that your query must visit each and every node in the graph in order to satisfy the query.
The problem would show itself in a relational database when a TABLE SCAN had to be used instead of an index.
I think the solution is to add buckets for hours, like you already have for days. If you have to have minutes, make 96 fifteen minute buckets to cover a day. That will give the query optimizer its best chance.