Estoy tratando de crear una consulta usando cifrado que "encontrará" los ingredientes faltantes que un chef podría tener. Mi gráfico está configurado así:
(ingredient_value)-[:is_part_of]->(ingredient)
(ingredient)
tendría una clave / valor de name = "dye colors". (ingredient_value)
podría tener una clave / valor de valor = "rojo" y "es parte de" (ingredient, name="dye colors")
.
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
Estoy usando esta consulta para obtener todos los ingredients
valores, pero no sus valores reales, que requiere una receta, pero me gustaría devolver solo lo ingredients
que el chef no tiene, en lugar de todos los ingredientes que requiere cada receta. Lo intenté
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef
pero esto no devolvió nada.
¿Es esto algo que puede lograr cypher / neo4j o es algo que se maneja mejor devolviendo todos los ingredientes y clasificándolos yo mismo?
Bono: también hay una manera de usar cypher para hacer coincidir todos los valores que tiene un chef con todos los valores que requiere una receta. Hasta ahora, solo he devuelto todas las coincidencias parciales que son devueltas por chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
ay agregando los resultados yo mismo.
exists
en unaWHERE
cláusula (también negarla ), neo4j.com/developer/subqueries/#existential-subqueries para obtener más información.Respuestas:
Actualización 10/01/2013:
Encontré esto en la referencia de Neo4j 2.0 :
Trate de no usar relaciones opcionales. Sobre todo,
no los use así:
MATCH a-[r?:LOVES]->() WHERE r IS NULL
donde solo te aseguras de que no existan.En su lugar, haz esto así:
Usando cifrado para verificar si la relación no existe:
Los ? marca hace que la relación sea opcional.
O
En neo4j 2 haz:
Ahora puede verificar la relación no existente (nula).
fuente
MATCH a...
ejemplo debería ser ahoraMATCH (a) WHERE NOT (a)-[:LOVES]->()
Para buscar nodos sin ninguna relación
Esta es la buena opción para verificar si la relación existe o no
También puede verificar múltiples condiciones para esto. Devolverá todos los nodos, que no tengan la relación "jugado" o "no jugado".
Para buscar nodos que no tengan ninguna relación.
Verificará que el nodo no tenga ninguna relación entrante / saliente.
fuente
MATCH (player) WHERE NOT (player)-[r]-() RETURN player
da error Variable r no definido . ¿Cómo puedo definir r?(player -[:rel]- ()
) o déjelo vacío para cualquier relación(player -[]- ()
MATCH (player) WHERE NOT (player)-[]-() RETURN player
- Funciona bienSi necesita una semántica de "exclusión condicional", puede lograrlo de esta manera.
A partir de neo4j 2.2.1, puede usar la
OPTIONAL MATCH
cláusula y filtrar losNULL
nodos no coincidentes ( ).También es importante utilizar una
WITH
cláusula entre las cláusulasOPTIONAL MATCH
yWHERE
, de modo que la primeraWHERE
defina una condición para la coincidencia opcional y la segunda seWHERE
comporte como un filtro.Suponiendo que tenemos 2 tipos de nodos:
Person
yCommunication
. Si quiero obtener todas las Personas que nunca se han comunicado por teléfono, pero que pueden haberse comunicado de otras formas, haría esta consulta:El patrón de coincidencia coincidirá con todas las Personas con sus comunicaciones donde
c
seránNULL
para Comunicaciones no telefónicas. Luego, el filtro (WHERE
despuésWITH
) filtrará las comunicaciones telefónicas dejando todas las demás.Referencias:
http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional
fuente
Escribí una esencia que muestra cómo se puede hacer esto de forma bastante natural usando Cypher 2.0
http://gist.neo4j.org/?9171581
El punto clave es usar una combinación opcional para los ingredientes disponibles y luego comparar con el filtro los ingredientes faltantes (nulos) o los ingredientes con el valor incorrecto.
Tenga en cuenta que la noción es declarativa y no necesita describir un algoritmo, solo escriba lo que necesita.
fuente
Completé esta tarea usando gremlin. yo hice
Esto devolvió los caminos de todos los ingredientes faltantes. No pude formular esto en el lenguaje cifrado, al menos para la versión 1.7.
fuente
La última consulta debería ser:
Este patrón:
(ingredient)<-[:has_ingredient*0..0]-chef
Es la razón por la que no devolvió nada.
*0..0
significa que la longitud de las relaciones debe ser cero, lo que significa que el ingrediente y el chef deben ser el mismo nodo, lo que no es así.fuente