tengo un problema con neo4j. No sé si el problema es mi consulta o algo más.
Introducción
Tengo que construir una aplicación que almacene rutas de autobús/tren. Este es mi esquema:
Nodos :
Relaciones importantes :
Las relaciones NEXT contienen esas propiedades:
Problema
mi consulta es:
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 10Por ejemplo: quiero encontrar todas las siguientes relaciones donde el día de la semana sea el domingo (0) y la propiedad startHour > 11
Después de eso, generalmente analizo y valido el objeto final en mi backend de nodejs.
Esto funciona cuando estaba al principio... con 1k relaciones... Ahora tengo 10k relaciones y mi consulta tiene un problema de TIMEOUT o las consultas se resuelven en 30 segundos... demasiado tiempo... No tengo idea de cómo resolver esto. Uso neo4j con docker e intenté leer los documentos de configuración, pero no tengo idea de cómo funciona Java.
¿Pueden ayudarme chicos?
ACTUALIZAR
¡Gracias a todos, chicos! Por ahora resolví con "allShortestPaths" pero creo que cambiaré el nombre de todas las relaciones (como dijo Michael Hunger).
Has probado:
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 10Esto debería usar el algoritmo de ruta rápida más corta porque:
La planificación de las rutas más cortas en Cypher puede dar lugar a diferentes planes de consulta según los predicados que deben evaluarse. Internamente, Neo4j utilizará un algoritmo de búsqueda rápido bidireccional primero en anchura si los predicados se pueden evaluar mientras se busca la ruta.
Consulte https://neo4j.com/docs/developer-manual/current/cypher/execution-plans/shortestpath-planning/#_shortest_path_with_fast_algorithm para obtener más detalles.
¿Puedes compartir tu perfil?
Supongo que tiene una restricción en :Stop(id)
Usaría la ruta más corta o dijkstra con costos en lugar de la coincidencia opcional. OPTIONAL MATCH intentará encontrar TODOS esos caminos que son cientos de millones y los filtrará a medida que avanzan.
Y podría tener sentido agrupar sus NEXT relaciones por día de la semana, por ejemplo, :NEXT_MO, :NEXT_THU para que solo mire 1/7 de los datos.
No es la configuración; es el hecho de que su consulta debe visitar todos y cada uno de los nodos del gráfico para satisfacer la consulta.
El problema se mostraría en una base de datos relacional cuando se tuviera que usar un TABLE SCAN en lugar de un índice.
Creo que la solución es agregar cubos por horas, como ya lo ha hecho por días. Si tiene que tener minutos, haga 96 cubos de quince minutos para cubrir un día. Eso le dará al optimizador de consultas su mejor oportunidad.