Clausula Start
Es una clausula opcional desde la versión 2.0, antes esta clausula era obligatoria.Se utiliza para indicar el punto o los puntos de partida de un query. Ahora si no se especifica, Neo4j intentará inferir los puntos de partida de la query mediante los Labels y los predicados de la query.
Neo4j asigna un Identificador a cada nodo que se crea, este Id se puede usar para indicar un nodo como punto de partida de una query.
Si por ejemplo queremos especificar nosotros un punto de partida especifico es posible hacer referencia a un nodo mediante su id.
start n=node(0) return n
Pero sin embargo Neo4j reutiliza sus identificadores internos cuando se eliminan los nodos y las relaciones, lo que significa que es una mala práctica referirse a ellos de esta manera. En su lugar se recomienda generar identificadores propios y almacenarlos en el nodo como propiedades.
Otro de los usos que podemos dar a la clausula START es cuando queremos identificar puntos de partida haciendo uso de Full-Text Index, pero para no extenderme mucho más con la clausula START ya que es opcional, os dejo un enlace a un post Full-Text-Indexing (FTS) in Neo4j 2.0 de Michael Hunger, donde habla sobre este tema.
Clausula Match
Es la forma principal de obtener datos en Neo4j.Esquema de una query
El esquema de una query con Match recuperar datos con Cypher es:MATCH (n) RETURN n
Con la clausula Match especificamos un patrón a cumplir, en este caso simplemente no indicamos nada o lo que es lo mismo que sea un nodo cualquiera. Esta es la estructura de búsqueda más básica. En Neo4j como ya hemos visto en anteriores post, el tiempo de respuesta de una query depende del recorrido a realizar no del volumen de datos, por esto es fundamental tener el inicio del recorrido lo más acotado posible.
En el ejemplo anterior recorreríamos todos los nodos y devolveríamos todos los nodos. Con un grafo muy grande este tipo de consulta no es recomendable.
Match con Filtros de Labels
En la clausula Match podemos especificar Labels acotando el tipo de nodo a devolver
MATCH (user:User) RETURN user
Esta query nos devolvería todos los usuarios de la base de datos
Match con Filtros de propiedades
En la clausula Match podemos especificar filtros de propiedades
MATCH (user:User{ name:'user 1' }) RETURN user
Esta query nos devolvería todos los usuarios con el nombre 'user 1'
Match con Filtros de relaciones
En la clausula Match podemos especificar filtros de relaciones
MATCH (user:User{ name:'user 1' })-[:BUY]->(p) RETURN user,p
Esta query nos devolvería todos los usuarios con el nombre 'user 1' y los productos que han comprado.
Clausula Where
Sirve para filtrar los resultados del subgrafo a crear para una query
Esquema de una query
El esquema de una query con Where recuperar datos con Cypher es:MATCH (n) WHERE n.propiedad = 'valor' RETURN n
Con la clausula Where filtramos los resultados
Where con Filtros de Labels
En la clausula Where podemos especificar Labels acotando el tipo de nodo a devolver
MATCH (user) WHERE user:User RETURN user
Esta query nos devolvería todos los usuarios de la base de datos
Where con Filtros de propiedades
En la clausula Where podemos especificar filtros de propiedades
MATCH (user:User) WHERE user.name = 'user 1' RETURN user
Esta query nos devolvería todos los usuarios con el nombre 'user 1'
Match con Filtros de relaciones
En la clausula Match podemos especificar filtros de relaciones
MATCH (user),(p) WHERE user:User and user.name = 'user 1' and user-[:BUY]->(p) RETURN user,p
Esta query nos devolvería todos los usuarios con el nombre 'user 1' y los productos que han comprado.
Resumen
Hemos visto la clausula Start que no es obligatoria y las clausulas Match y Where. En la clausula Match se pueden poner más de un patrón con comas y en la clausula Where no se pueden poner comas pero si con operadores and y or. Match y Where pueden parecer parecidas porque pueden generar el mismo resultado en queries utilizando ambos, pero sus objetivos son totalmente diferentes
Si vemos estos dos ejemplos:
Si vemos estos dos ejemplos:
MATCH (user:User{ name:'user 1' })-[:BUY]->(p) RETURN user,p
MATCH (user),(p) WHERE user:User and user.name = 'user 1' and user-[:BUY]->(p) RETURN user,p
En la primera query se genera un subgrafo de los nodos que que cumplen el patrón Match, en el segundo sin embargo, se genera un subgrafo con todos los nodos y se eliminan los que no cumplen el patrón Where. Por lo tanto la primera query es más optima que la segunda.
¿Entonces cuando utilizamos la clausula where?
Pues un poco de sentido común, lo normal es declarar el patrón de búsqueda principal en el Match y luego con el Where hacer un refinamiento del grafo a tratar.
Siento que me quedan muchas cosas por contar de Neo4j y Cypher, pero la idea era hacer unos post de introducción que no quedarán excesivamente largos y que fueran una introducción.
El manual de Neo4j es bastante completo, así que recomiendo que recurráis a el para profundizar.
Tengo en mente hacer futuros post planteando ejemplos más complejos y mas orientado a problemas reales para los que neo4j es realmente bueno.
Libros Relacionados
Graph DatabasesNeo4j in Action
A Programmatic Introduction to Neo4j
Muchas gracias, quería hacer una recuperacion de datos de mi equipo y tu ayuda me ha venido de perlas!
ResponderEliminar