Reescritura de consultas de Cypher para ejecutarlas en Neptune openCypher - Amazon Neptune

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Reescritura de consultas de Cypher para ejecutarlas en Neptune openCypher

El openCypher lenguaje es un lenguaje de consulta declarativo para gráficos de propiedades que fue desarrollado originalmente por Neo4j, luego de código abierto en 2015 y contribuido al proyecto bajo una licencia de código abierto de Apache 2. openCypher En AWS, creemos que el código abierto es bueno para todos y estamos comprometidos a llevar el valor del código abierto a nuestros clientes y la excelencia operativa de las comunidades de AWS código abierto.

OpenCypher La sintaxis está documentada en la versión 9 de Cypher Query Language Reference.

Como openCypher contiene un subconjunto de la sintaxis y las características del lenguaje de consultas Cypher, algunos escenarios de migración requieren reescribir las consultas en formatos openCypher compatibles o examinar métodos alternativos para lograr la funcionalidad deseada.

En esta sección se incluyen recomendaciones para tratar las diferencias más comunes, pero no es en absoluto exhaustiva. Debe probar minuciosamente cualquier aplicación que utilice estas reescrituras para asegurarse de que los resultados son los previstos.

Reescritura de funciones de predicado None, All y Any

Estas funciones no forman parte de la especificación. openCypher Se pueden lograr resultados comparables al openCypher utilizar la comprensión de listas.

Por ejemplo, busque todas las rutas que van del nodo Start al nodo End, pero no se permite que ningún recorrido atraviese un nodo con una propiedad de clase de D:

# Neo4J Cypher code match p=(a:Start)-[:HOP*1..]->(z:End) where none(node IN nodes(p) where node.class ='D') return p # Neptune openCypher code match p=(a:Start)-[:HOP*1..]->(z:End) where size([node IN nodes(p) where node.class = 'D']) = 0 return p

La opción Comprensión de listas puede lograr los siguientes resultados:

all => size(list_comprehension(list)) = size(list) any => size(list_comprehension(list)) >= 1 none => size(list_comprehension(list)) = 0

Reescribiendo la función reduce() Cypher en openCypher

La reduce() función no forma parte de la especificación. openCypher Suele utilizarse para crear una agregación de datos a partir de elementos de una lista. En muchos casos, puede utilizar una combinación de Comprensión de listas y la cláusula UNWIND para obtener resultados similares.

Por ejemplo, la siguiente consulta de Cypher busca todos los aeropuertos de las rutas que tienen de una a tres paradas entre Anchorage (ANC) y Austin (AUS) y devuelve la distancia total de cada ruta:

MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'}) RETURN p, reduce(totalDist=0, r in relationships(p) | totalDist + r.dist) AS totalDist ORDER BY totalDist LIMIT 5

Puede escribir la misma consulta openCypher para Neptune de la siguiente manera:

MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'}) UNWIND [i in relationships(p) | i.dist] AS di RETURN p, sum(di) AS totalDist ORDER BY totalDist LIMIT 5

Reescribiendo la cláusula FOREACH Cypher en openCypher

La FOREACH cláusula no forma parte de la especificación. openCypher Suele utilizarse para actualizar los datos en mitad de una consulta, a menudo a partir de agregaciones o elementos de una ruta.

Como ejemplo de ruta, busque todos los aeropuertos en una ruta con no más de dos paradas entre Anchorage (ANC) y Austin (AUS) y establezca una propiedad de visitado en cada uno de ellos:

# Neo4J Example MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'}) FOREACH (n IN nodes(p) | SET n.visited = true) # Neptune openCypher MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'}) WITH nodes(p) as airports UNWIND airports as a SET a.visited=true

Otro ejemplo:

# Neo4J Example MATCH p=(start)-[*]->(finish) WHERE start.name = 'A' AND finish.name = 'D' FOREACH (n IN nodes(p) | SET n.marked = true) # Neptune openCypher MATCH p=(start)-[*]->(finish) WHERE start.name = 'A' AND finish.name = 'D' UNWIND nodes(p) AS n SET n.marked = true

Reescribiendo los procedimientos de Neo4j APOC en Neptune

Los ejemplos siguientes se utilizan openCypher para reemplazar algunos de los procedimientos más utilizados. APOC Estos ejemplos son solo de referencia y están destinados a proporcionar algunas sugerencias sobre cómo gestionar situaciones comunes. En la práctica, cada aplicación es diferente y tendrá que idear sus propias estrategias para proporcionar toda la funcionalidad que necesite.

Reescritura de los procedimientos de apoc.export

Neptune ofrece una variedad de opciones para exportaciones basadas en consultas y gráficos completos en varios formatos de salidaJSON, como CSV y mediante la utilidad neptune-export (consulte). Exportación de datos desde un clúster de base de datos de Neptune

Reescritura de los procedimientos de apoc.schema

Neptune no tiene esquemas, índices ni restricciones definidos de forma explícita, por lo que muchos procedimientos de apoc.schema ya no son necesarios. Algunos ejemplos son:

  • apoc.schema.assert

  • apoc.schema.node.constraintExists

  • apoc.schema.node.indexExists,

  • apoc.schema.relationship.constraintExists

  • apoc.schema.relationship.indexExists

  • apoc.schema.nodes

  • apoc.schema.relationships

Neptune openCypher admite la recuperación de valores similares a los de los procedimientos, como se muestra a continuación, pero puede tener problemas de rendimiento en gráficos más grandes, ya que para hacerlo es necesario escanear una gran parte del gráfico para obtener la respuesta.

# openCypher replacement for apoc.schema.properties.distinct MATCH (n:airport) RETURN DISTINCT n.runways
# openCypher replacement for apoc.schema.properties.distinctCount MATCH (n:airport) RETURN DISTINCT n.runways, count(n.runways)

Alternativas a los procedimientos de apoc.do

Estos procedimientos se utilizan para proporcionar una ejecución de consultas condicional que es fácil de implementar con otras openCypher cláusulas. En Neptune hay al menos dos formas de lograr un comportamiento similar:

  • Una forma es combinar las capacidades openCypher de comprensión de listas con la UNWIND cláusula.

  • Otra forma es usar los pasos choose() y coalesce() de Gremlin.

A continuación se muestran ejemplos de estos enfoques.

Alternativas a apoc.do.when

# Neo4J Example MATCH (n:airport {region: 'US-AK'}) CALL apoc.do.when( n.runways>=3, 'SET n.is_large_airport=true RETURN n', 'SET n.is_large_airport=false RETURN n', {n:n} ) YIELD value WITH collect(value.n) as airports RETURN size([a in airports where a.is_large_airport]) as large_airport_count, size([a in airports where NOT a.is_large_airport]) as small_airport_count # Neptune openCypher MATCH (n:airport {region: 'US-AK'}) WITH n.region as region, collect(n) as airports WITH [a IN airports where a.runways >= 3] as large_airports, [a IN airports where a.runways < 3] as small_airports, airports UNWIND large_airports as la SET la.is_large_airport=true WITH DISTINCT small_airports, airports UNWIND small_airports as la SET la.small_airports=true WITH DISTINCT airports RETURN size([a in airports where a.is_large_airport]) as large_airport_count, size([a in airports where NOT a.is_large_airport]) as small_airport_count #Neptune Gremlin using choose() g.V(). has('airport', 'region', 'US-AK'). choose( values('runways').is(lt(3)), property(single, 'is_large_airport', false), property(single, 'is_large_airport', true)). fold(). project('large_airport_count', 'small_airport_count'). by(unfold().has('is_large_airport', true).count()). by(unfold().has('is_large_airport', false).count()) #Neptune Gremlin using coalesce() g.V(). has('airport', 'region', 'US-AK'). coalesce( where(values('runways').is(lt(3))). property(single, 'is_large_airport', false), property(single, 'is_large_airport', true)). fold(). project('large_airport_count', 'small_airport_count'). by(unfold().has('is_large_airport', true).count()). by(unfold().has('is_large_airport', false).count())

Alternativas a apoc.do.case

# Neo4J Example MATCH (n:airport {region: 'US-AK'}) CALL apoc.case([ n.runways=1, 'RETURN "Has one runway" as b', n.runways=2, 'RETURN "Has two runways" as b' ], 'RETURN "Has more than 2 runways" as b' ) YIELD value RETURN {type: value.b,airport: n} # Neptune openCypher MATCH (n:airport {region: 'US-AK'}) WITH n.region as region, collect(n) as airports WITH [a IN airports where a.runways =1] as single_runway, [a IN airports where a.runways =2] as double_runway, [a IN airports where a.runways >2] as many_runway UNWIND single_runway as sr WITH {type: "Has one runway",airport: sr} as res, double_runway, many_runway WITH DISTINCT double_runway as double_runway, collect(res) as res, many_runway UNWIND double_runway as dr WITH {type: "Has two runways",airport: dr} as two_runways, res, many_runway WITH collect(two_runways)+res as res, many_runway UNWIND many_runway as mr WITH {type: "Has more than 2 runways",airport: mr} as res2, res, many_runway WITH collect(res2)+res as res UNWIND res as r RETURN r #Neptune Gremlin using choose() g.V(). has('airport', 'region', 'US-AK'). project('type', 'airport'). by( choose(values('runways')). option(1, constant("Has one runway")). option(2, constant("Has two runways")). option(none, constant("Has more than 2 runways"))). by(elementMap()) #Neptune Gremlin using coalesce() g.V(). has('airport', 'region', 'US-AK'). project('type', 'airport'). by( coalesce( has('runways', 1).constant("Has one runway"), has('runways', 2).constant("Has two runways"), constant("Has more than 2 runways"))). by(elementMap())

Alternativas a las propiedades basadas en listas

Neptune no admite actualmente el almacenamiento de propiedades basadas en listas. Sin embargo, se pueden obtener resultados similares si se almacenan los valores de la lista como una cadena separada por comas y, a continuación, se utilizan las funciones join() y split() para construir y deconstruir la propiedad de la lista.

Por ejemplo, si quisiéramos guardar una lista de etiquetas como una propiedad, podríamos usar el ejemplo de reescritura, que muestra cómo recuperar una propiedad separada por comas, y luego usar las funciones split() y join() con Compresión de listas para lograr resultados comparables:

# Neo4j Example (In this example, tags is a durable list of string. MATCH (person:person {name: "TeeMan"}) WITH person, [tag in person.tags WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags SET person.tags = newTags RETURN person # Neptune openCypher MATCH (person:person {name: "TeeMan"}) WITH person, [tag in split(person.tags, ',') WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags SET person.tags = join(newTags,',') RETURN person

CALLReescribir las subconsultas

CALLLas subconsultas de Neptune no admiten la sintaxis CALL (friend) { ... } para importar variables al ámbito de la subconsulta (friend, en este ejemplo). Utilice la WITH cláusula incluida en la subconsulta para hacer lo mismo, por ejemplo,. CALL { WITH friend ... }

CALLLas subconsultas opcionales no se admiten en este momento.

Otras diferencias entre Neptune openCypher y Cypher

  • Neptune solo admite TCP conexiones para el protocolo Bolt. WebSocketsno se admiten las conexiones para Bolt.

  • Neptune openCypher elimina los espacios en blanco tal y como los define Unicode en las funciones y. trim() ltrim() rtrim()

  • En NeptuneopenCypher, el tostring( doble ) no cambia automáticamente a la notación E para valores grandes del doble.