Nodo de retorno si la relación no está presente
Estoy tratando de crear una consulta usando cypher que "Encontrará" los ingredientes faltantes que un chef podría tener, Mi gráfico está configurado de la siguiente manera:
(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 value="red" y "is part of" el (ingredient, name="dye colors")
.
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
Estoy usando esta consulta para obtener todos los ingredients
, pero no sus valores reales, que una receta requiere, pero me gustaría que el retorno solo el 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 se puede lograr mediante cypher/neo4j o es esto algo que se maneja mejor devolviendo todos los ingredientes y clasificándolos yo mismo?
Bono: También hay una manera de utilizar el cifrado para que coincida con todos los valores que un chef tiene a todos los valores que una receta requiere. Hasta ahora solo he devuelto todas las coincidencias parciales que son devueltas por un chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
y agregando los resultados yo mismo.
6 answers
Actualizar 01/10/2013:
Se encontró con esto en el Neo4j 2.0 referencia:
Trate de no usar relaciones opcionales. Sobre todo,
no los uses así.:
MATCH a-[r?:LOVES]->() WHERE r IS NULL
donde te aseguras de que no existan.
En su lugar hacer esto como así:
MATCH a WHERE NOT (a)-[:LOVES]->()
Usando cypher para comprobar si la relación no existe:
...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source
El ? marca la relación opcional.
O
En neo4j 2 do:
...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source
Ahora puede comprobar si existe una relación inexistente (nula).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 10:10:43
Para obtener nodos sin ninguna relación
Esta es la buena opción para comprobar que la relación existe o no
MATCH (player)-[r:played]->()
WHERE r IS NULL
RETURN player
También puede verificar múltiples condiciones para esto Devolverá todos los nodos, que no tienen Relación" played "O" notPlayed".
MATCH (player)
WHERE NOT (player)-[:played|notPlayed]->()
RETURN player
Para obtener los nodos que no tener ninguna relacion
MATCH (player)
WHERE NOT (player)-[r]-()
RETURN player
Comprobará que el nodo no tiene ninguna relación entrante/saliente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-21 08:36:18
Si necesita "exclusión condicional" semántica, puede lograrlo de esta manera.
A partir de neo4j 2.2.1, puede usar la cláusula OPTIONAL MATCH
y filtrar los nodos no coincidentes(NULL
).
También es importante usar la cláusula WITH
entre las cláusulas OPTIONAL MATCH
y WHERE
, para que WHERE
se comporte como un filtro, no como parte del patrón de coincidencia.
Suponiendo que tenemos 2 tipos de nodos: Person
y Communication
. Si quiero conseguir a todas las Personas que nunca se han comunicado por teléfono, pero pueden tener comunicado de otras maneras, me gustaría hacer esta consulta:
MATCH (p: Person)
OPTIONAL MATCH p--(c: Communication)
WHERE c.way = 'telephone'
WITH p, c
WHERE c IS NULL
RETURN p
Tenga en cuenta que la primera cláusula WHERE
se comporta como una parte de la coincidencia.
Referencias:
Http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-02 17:16:22
Escribí un gist mostrando cómo esto se puede hacer de forma natural usando Cypher 2.0
Http://gist.neo4j.org/?9171581
El punto clave es usar la coincidencia opcional con los ingredientes disponibles y luego comparar con filtrar por ingredientes faltantes (nulos) o 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-23 14:13:40
Completé esta tarea usando gremlin. Lo hice
x=[]
g.idx('Chef')[[name:'chef1']].as('chef')
.out('has_ingredient').as('alreadyHas').aggregate(x).back('chef')
.out('has_value').as('values')
.in('requires_value').as('recipes')
.out('requires_ingredient').as('ingredients').except(x).path()
Esto devolvió los caminos de todos los ingredientes faltantes. No pude formular esto en el lenguaje cypher, al menos para la versión 1.7.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-26 11:27:59
La última consulta debe ser:
START chef = node(..)
MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
WHERE (ingredient)<-[:has_ingredient]-chef
RETURN ingredient
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 ingredient y chef deben ser el mismo nodo, que no lo son.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 10:15:08