tutorial sheet node downloads create cheat neo4j cypher

sheet - ¿Por qué advierte neo4j: "Esta consulta crea un producto cartesiano entre patrones desconectados"?



neo4j enterprise (2)

Como logisima menciona en los comentarios, esto es solo una advertencia. Hacer coincidir un producto cartesiano es lento. En su caso, debería estar bien, ya que desea conectar nodos de Chromosome y Gene previamente desconectados y conoce el tamaño del producto cartesiano. No hay demasiados cromosomas y una pequeña cantidad de genes. Si usted MATCH por ejemplo, genes en proteínas, la consulta podría explotar.

Creo que la advertencia está destinada a otras consultas problemáticas:

  • si MATCH un producto cartesiano pero no sabes si existe una relación, podrías usar OPTIONAL MATCH
  • si desea MATCH tanto un Gene como un Chromosome sin ninguna relación, debe dividir la consulta

En caso de que su consulta tarde demasiado o no termine, aquí hay otra pregunta que da algunos consejos sobre cómo optimizar los productos cartesianos: Cómo optimizar las consultas Neo4j Cypher con coincidencias de múltiples nodos (Producto cartesiano)

Estoy definiendo la relación entre dos entidades, Gene y Cromosoma, en lo que creo que es la forma simple y normal, después de importar los datos de CSV:

MATCH (g:Gene),(c:Chromosome) WHERE g.chromosomeID = c.chromosomeID CREATE (g)-[:PART_OF]->(c);

Sin embargo, cuando lo hago, neo4j (interfaz de usuario del navegador) se queja:

Esta consulta crea un producto cartesiano entre patrones desconectados. Si una parte de una consulta contiene múltiples patrones desconectados, esto generará un producto cartesiano entre todas esas partes. Esto puede producir una gran cantidad de datos y ralentizar el procesamiento de consultas. Si bien ocasionalmente se pretende, a menudo es posible reformular la consulta que evita el uso de este producto cruzado, quizás agregando una relación entre las diferentes partes o utilizando OPCIONAL MATCH (el identificador es: (c)).

No veo cuál es el problema. chromosomeID es una clave externa muy sencilla.


El navegador te dice que:

  1. Está manejando su consulta haciendo una comparación entre cada instancia de Gene y cada instancia de Chromosome . Si su DB tiene genes G y cromosomas C , entonces la complejidad de la consulta es O(GC) . Por ejemplo, si estamos trabajando con el genoma humano, hay 46 cromosomas y quizás 25000 genes, por lo que el DB tendría que hacer 1150000 comparaciones.
  2. Es posible que pueda mejorar la complejidad (y el rendimiento) modificando su consulta. Por ejemplo, si creamos un índice en :Gene(chromosomeID) , y modificamos la consulta para que coincidamos inicialmente en el nodo con la cardinalidad más pequeña (los 46 cromosomas), solo haríamos O(G) (o 25000 ) "comparaciones" - ¡y esas comparaciones en realidad serían búsquedas rápidas de índices! Este enfoque debería ser mucho más rápido.

    Una vez que hemos creado el índice, podemos usar esta consulta:

    MATCH (c:Chromosome) WITH c MATCH (g:Gene) WHERE g.chromosomeID = c.chromosomeID CREATE (g)-[:PART_OF]->(c);

    Utiliza una cláusula WITH para forzar la ejecución de la primera cláusula MATCH , evitando el producto cartesiano. La segunda cláusula MATCH (y WHERE ) utiliza los resultados de la primera cláusula MATCH y el índice para obtener rápidamente los genes exactos que pertenecen a cada cromosoma.