openCypher 亚马逊 Neptune 中的规范合规性 - Amazon Neptune

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

openCypher 亚马逊 Neptune 中的规范合规性

Amazon Neptune 版本 openCypher 通常支持当前 openCypher 规范(即密码查询语言参考版本 9)中定义的子句、运算符、表达式、函数和语法。下面列出了 Neptune 支持的局限性和差异。 openCypher

注意

Cypher的当前Neo4j实现包含上述规范中未包含的 openCypher 功能。如果您要将当前 Cypher 代码迁移到 Neptune,请参阅Neptune 与 Neo4j 的兼容性重写 Cypher 查询以在 Neptune 上的 openCypher 中运行以了解更多信息。

支持 Neptune 中的子 openCypher 句

除非另有说明,否则 Neptune 支持以下子句:

  • MATCH— 支持,除此之外 shortestPath() 以及 allShortestPaths() 目前不支持。

  • OPTIONAL MATCH

  • MANDATORY MATCH   — 目前在 Neptune 中支持。但是,Neptune 确实支持在 MATCH 查询中使用自定义 ID 值

  • RETURN – 支持,但与 SKIPLIMIT 的非静态值结合使用时除外。例如,以下内容目前不起作用:

    MATCH (n) RETURN n LIMIT toInteger(rand()) // Does NOT work!
  • WITH – 支持,但与 SKIPLIMIT 的非静态值结合使用时除外。例如,以下内容目前不起作用:

    MATCH (n) WITH n SKIP toInteger(rand()) WITH count() AS count RETURN count > 0 AS nonEmpty // Does NOT work!
  • UNWIND

  • WHERE

  • ORDER BY

  • SKIP

  • LIMIT

  • CREATE – Neptune 允许您在 CREATE 查询中创建自定义 ID 值

  • DELETE

  • SET

  • REMOVE

  • MERGE – Neptune 支持在 MERGE 查询中使用自定义 ID 值

  • CALL[YIELD...]   — 目前在 Neptune 中支持。

  • UNION, UNION ALL – 支持只读查询,但目前支持突变查询。

  • USINGUSING 引擎版本 1.3.2. 0 支持。有关更多信息,请参阅查询提示

Support 为 Neptune 中的 openCypher 运算符提供支持

除非另有说明,否则 Neptune 支持以下运算符:

一般运算符
  • DISTINCT

  • 用于访问嵌套文本映射的属性的 . 运算符。

数学运算
  • + 加法运算符。

  • - 减法运算符。

  • * 乘法运算符。

  • / 除法运算符。

  • % 模除运算符。

  • ^指数运算符 is NOT supported.

比较运算符
  • = 加法运算符。

  • <> 不等于运算符。

  • 支持 < 小于运算符,除非其中一个参数是路径、列表或映射。

  • 支持 > 大于运算符,除非其中一个参数是路径、列表或映射。

  • 支持 <= less-than-or-equal-to 运算符,除非其中一个参数是路径、列表或地图。

  • 支持 >= greater-than-or-equal-to 运算符,除非其中一个参数是路径、列表或地图。

  • IS NULL

  • IS NOT NULL

  • 如果要搜索的数据是字符串,则支持 STARTS WITH

  • 如果要搜索的数据是字符串,则支持 ENDS WITH

  • 如果要搜索的数据是字符串,则支持 CONTAINS

布尔运算符
  • AND

  • OR

  • XOR

  • NOT

字符串运算符
  • + 联接运算符。

列表运算符
  • + 联接运算符。

  • IN(检查列表中是否存在某个项目)

支持 Neptune 中的 openCypher 表达式

除非另有说明,否则 Neptune 支持以下表达式:

  • CASE

  • Neptune 目前支持使用 [] 表达式来访问节点、关系或映射中动态计算的属性键。例如,以下内容不起作用:

    MATCH (n) WITH [5, n, {key: 'value'}] AS list RETURN list[1].name

支持 Neptune 中的 openCypher 函数

除非另有说明,否则 Neptune 支持以下函数:

谓词函数
  • exists()

标量函数
  • coalesce()

  • endNode()

  • epochmillis()

  • head()

  • id()

  • last()

  • length()

  • randomUUID()

  • properties()

  • removeKeyFromMap

  • size() – 此重载方法目前仅适用于模式表达式、列表和字符串

  • startNode()

  • timestamp()

  • toBoolean()

  • toFloat()

  • toInteger()

  • type()

聚合函数
  • avg()

  • collect()

  • count()

  • max()

  • min()

  • percentileDisc()

  • stDev()

  • percentileCont()

  • stDevP()

  • sum()

列出函数
  • join()(将列表中的字符串联接成单个字符串)

  • keys()

  • labels()

  • nodes()

  • range()

  • relationships()

  • reverse()

  • tail()

数学函数 - 数字
  • abs()

  • ceil()

  • floor()

  • rand()

  • round()

  • sign()

数学函数 - 对数
  • e()

  • exp()

  • log()

  • log10()

  • sqrt()

数学函数 - 三角函数
  • acos()

  • asin()

  • atan()

  • atan2()

  • cos()

  • cot()

  • degrees()

  • pi()

  • radians()

  • sin()

  • tan()

字符串函数
  • join()(将列表中的字符串联接成单个字符串)

  • left()

  • lTrim()

  • replace()

  • reverse()

  • right()

  • rTrim()

  • split()

  • substring()

  • toLower()

  • toString()

  • toUpper()

  • trim()

用户定义的函数

User-defined functions Neptune 目前支持。

特定于海王星的实现细节 openCypher

以下各节描述了 Neptune 的实现 openCypher 可能与规范不同或超出规范的openCypher 方式。

Neptune 中的可变长度路径 (VLP) 求值

可变长度路径 (VLP) 求值会发现图形中节点之间的路径。查询中的路径长度可以不受限制。为了防止循环,该openCypher 规范规定每个解最多只能遍历每条边一次。

因为VLPs,Neptune 实现与 openCypher 规范的不同之处在于,它仅支持属性相等过滤器的常量值。执行以下查询:

MATCH (x)-[:route*1..2 {dist:33, code:x.name}]->(y) return x,y

由于 x.name 属性相等筛选条件值不是常量,因此,此查询会导致 UnsupportedOperationException,并显示消息:Property predicate over variable-length relationships with non-constant expression is not supported in this release.

Neptune openCypher 实现中的时间支持(海王星数据库 1.3.1.0 及更低版本)

Neptune目前为中的时间函数提供的支持有限. openCypher 它支持对时间类型使用 DateTime 数据类型。

datetime()函数可以用来获取当前的UTC日期和时间,如下所示:

RETURN datetime() as res

日期和时间值可以从 "dateTtime" 格式的字符串中解析,其中 datetime 都以下面支持的形式之一表示:

支持的日期格式
  • yyyy-MM-dd

  • yyyyMMdd

  • yyyy-MM

  • yyyy-DDD

  • yyyyDDD

  • yyyy

支持的时间格式
  • HH:mm:ssZ

  • HHmmssZ

  • HH:mm:ssZ

  • HH:mmZ

  • HHmmZ

  • HHZ

  • HHmmss

  • HH:mm:ss

  • HH:mm

  • HHmm

  • HH

例如:

RETURN datetime('2022-01-01T00:01') // or another example: RETURN datetime('2022T0001')

请注意,Neptune 中的所有日期/时间值 openCypher 都作为值存储和检索。UTC

Neptune openCypher 使用时statement钟,这意味着在整个查询过程中使用相同的时刻。同一事务中的不同查询可能会使用不同的时刻。

Neptune 不支持在对 datetime() 的调用中使用函数。例如,以下内容不起作用:

CREATE (:n {date:datetime(tostring(2021))}) // ---> NOT ALLOWED!

Neptune 确实支持将 datetime 转换为 epochmillisepochmillis() 函数。例如:

MATCH (n) RETURN epochMillis(n.someDateTime) 1698972364782

Neptune 目前对 DateTime 对象不支持其它函数和操作,例如加法和减法。

Neptune openCypher 实现中的时间支持(Neptune Analytics 和 Neptune 数据库 1.3.2.0 及更高版本)

以下日期时间功能 OpenCypher 适用于 Neptune Analytics。或者,您可以使用 labmode 参数DatetimeMillisecond=enabled在 Neptune 引擎发行版 1.3.2.0 及更高版本上启用以下日期时间功能。有关在 labmode 中使用此功能的更多详细信息,请参阅扩展的日期时间支持

  • Support 支持毫秒。即使毫秒为 0,日期时间文字也将始终以毫秒为单位返回。(之前的行为是截断毫秒。)

    CREATE (:event {time: datetime('2024-04-01T23:59:59Z')}) # Returning the date returns with 000 suffixed representing milliseconds MATCH(n:event) RETURN n.time as datetime { "results" : [ { "n" : { "~id" : "0fe88f7f-a9d9-470a-bbf2-fd6dd5bf1a7d", "~entityType" : "node", "~labels" : [ "event" ], "~properties" : { "time" : "2024-04-01T23:59:59.000Z" } } } ] }
  • 支持通过存储的属性或中间结果调用 datetime () 函数。例如,在此功能之前,无法进行以下查询。

    日期时间 () 而不是属性:

    // Create node with property 'time' stored as string CREATE (:event {time: '2024-04-01T23:59:59Z'}) // Match and return this property as datetime MATCH(n:event) RETURN datetime(n.time) as datetime

    日期时间 () 而不是中间结果:

    // Parse datetime from parameter UNWIND $list as myDate RETURN datetime(myDate) as d
  • 现在也可以保存上述情况下创建的日期时间属性。

    将日期时间从一个属性的字符串属性保存到另一个属性:

    // Create node with property 'time' stored as string CREATE (:event {time: '2024-04-01T23:59:59Z', name: 'crash'}) // Match and update the same property to datetime type MATCH(n:event {name: 'crash'}) SET n.time = datetime(n.time) // Match and update another node's property MATCH(e:event {name: 'crash'}) MATCH(n:server {name: e.servername}) SET n.time = datetime(e.time)

    使用带有 datetime 属性的参数批量创建节点:

    // Batch create from parameter UNWIND $list as events CREATE (n:crash) {time: datetime(events.time)} // Parameter value { "x":[ {"time":"2024-01-01T23:59:29", "name":"crash1"}, {"time":"2023-01-01T00:00:00Z", "name":"crash2"} ] }
  • Support 支持 ISO86 01 个日期时间格式的更大子集。请参阅下面的。

支持的格式

日期时间值的格式为 [日期] T [时间] [时区],其中 T 是分隔符。如果未提供明确的时区,则假定 UTC (Z) 为默认时区。

时区

支持的时区格式有:

  • +/-HH: mm

  • +/-HHmm

  • +/-HH

日期时间字符串中是否存在时区是可选的。如果时区偏移量为 0,则可以使用 Z 代替上面的时区后缀来表示时间。UTC支持的时区范围为-14:00 到 + 14:00。

Date

如果不存在时区,或者时区为 UTC (Z),则支持的日期格式如下:

注意

DDD指序数日期,表示一年中从 001 到 365(闰年为 366)之间的某一天。例如,2024-002 代表 2024 年 1 月 2 日。

  • yyyy-MM-dd

  • yyyyMMdd

  • yyyy-MM

  • yyyyMM

  • yyyy-DDD

  • yyyyDDD

  • yyyy

如果选择了 Z 以外的时区,则支持的日期格式仅限于以下几种:

  • yyyy-MM-dd

  • yyyy-DDD

  • yyyyDDD

支持的日期范围为 1400-01-01 到 9999-12-31。

时间

如果不存在 timezaone,或者时区为 UTC (Z),则支持的时间格式为:

  • HH:mm:ss.SSS

  • HH:mm:ss

  • HHmmss.SSS

  • HHmmss

  • HH:mm

  • HHmm

  • HH

如果选择了 Z 以外的时区,则支持的时间格式仅限于以下几种:

  • HH:mm:ss

  • HH:mm:ss.SSS

Neptune openCypher 语言语义的差异

Neptune 将节点和关系表示IDs为字符串而不是整数。ID 等于通过数据加载程序提供的 ID。如果该列有命名空间,则命名空间加上 ID。因此,id 函数返回的是字符串而不是整数。

INTEGER 数据类型限制为 64 位。使用 TOINTEGER 函数将较大的浮点值或字符串值转换为整数时,负值会被截断为 LLONG_MIN,正值被截断为 LLONG_MAX

例如:

RETURN TOINTEGER(2^100) > 9223372036854775807 RETURN TOINTEGER(-1 * 2^100) > -9223372036854775808

Neptune 特定的 join() 函数

Neptune 实现了一个规范中没有的join()函数。 openCypher 它根据字符串文本列表和字符串分隔符创建字符串文本。此函数采用两个参数:

  • 第一个参数是字符串文本列表。

  • 第二个参数是分隔符字符串,可以包含零个、一个或多个字符。

例如:

join(["abc", "def", "ghi"], ", ") // Returns "abc, def, ghi"

Neptune 特定的 removeKeyFromMap() 函数

Neptune 实现了一个规范中没有的removeKeyFromMap()函数。 openCypher 它从映射中移除指定的键并返回生成的新映射。

此函数采用两个参数:

  • 第一个参数是从中移除键的映射。

  • 第二个参数是从映射中移除的键。

当您想通过展开映射列表来设置节点或关系的值时,removeKeyFromMap() 函数特别有用。例如:

UNWIND [{`~id`: 'id1', name: 'john'}, {`~id`: 'id2', name: 'jim'}] as val CREATE (n {`~id`: val.`~id`}) SET n = removeKeyFromMap(val, '~id')

节点和关系属性的自定义 ID 值

引擎版本 1.2.0.2 开始,Neptune 扩展了 openCypher 规范,因此您现在可以在CREATEMERGE和子句中为节点和关系指定id值。MATCH这使您可以分配用户友好的字符串,而不是系统生成的字符串UUIDs,以识别节点和关系。

警告

该 openCypher 规范的此扩展向后不兼容,因为~id现在被视为保留的属性名称。如果您已经在数据和查询中将 ~id 用作属性,则需要将现有属性迁移到新的属性键并移除旧的属性键。请参阅 如果您目前正在将 ~id 用作属性,该怎么办

以下示例展示了如何创建具有自定义功能的节点和关系IDS:

CREATE (n {`~id`: 'fromNode', name: 'john'}) -[:knows {`~id`: 'john-knows->jim', since: 2020}] ->(m {`~id`: 'toNode', name: 'jim'})

如果您尝试创建已在使用的自定义 ID,Neptune 会引发 DuplicateDataException 错误。

以下是在 MATCH 子句中使用一个自定义 ID 的示例:

MATCH (n {`~id`: 'id1'}) RETURN n

以下是在子MERGE句中使用 custom IDs 的示例:

MATCH (n {name: 'john'}), (m {name: 'jim'}) MERGE (n)-[r {`~id`: 'john->jim'}]->(m) RETURN r

如果您目前正在将 ~id 用作属性,该怎么办

引擎版本 1.2.0.2 中, openCypher 子句中的~id键现在被视为id属性而不是属性。这意味着,如果您有一个名为 ~id 的属性,则无法对其进行访问。

如果您使用的是 ~id 属性,那么在升级到引擎版本 1.2.0.2 或更高版本之前,您要做的就是先将现有 ~id 属性迁移到新的属性键,然后移除 ~id 属性。例如,下面的查询:

  • 为所有节点创建一个名为 newId “” 的新属性,

  • 将 '~id' 属性的值复制到 'newId' 属性中,

  • 并从数据中移除“~id”属性

MATCH (n) WHERE exists(n.`~id`) SET n.newId = n.`~id` REMOVE n.`~id`

对于数据中具有 ~id 属性的任何关系,都需要做同样的事情。

您还必须更改您正在使用的任何引用 ~id 属性的查询。例如,此查询:

MATCH (n) WHERE n.`~id` = 'some-value' RETURN n

...会改成这样:

MATCH (n) WHERE n.newId = 'some-value' RETURN n

Neptune 和 Cypher openCypher 之间的其他区别

  • Neptune 仅支持 Bolt 协议的TCP连接。 WebSockets不支持螺栓连接。

  • Neptune openCypher 会移除 Unicode 在、和函数中定义的空白。trim() ltrim() rtrim()

  • 在 Neptune 中openCypher,对于较大的tostring(双精度值,双精度)不会自动切换到 E 表示法。

  • 尽管 openCypher CREATE不创建多值属性,但它们可以存在于使用 Gremlin 创建的数据中。如果 Neptune openCypher 遇到多值属性,则任意选择其中一个值,从而产生不确定性的结果。