本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
openCypher 亚马逊 Neptune 中的规范合规性
Amazon Neptune 版本 openCypher 通常支持当前 openCypher 规范(即密码查询语言参考版本 9)中定义的子句、运算符、表达式、函数和语
注意
Cypher的当前Neo4j实现包含上述规范中未包含的 openCypher 功能。如果您要将当前 Cypher 代码迁移到 Neptune,请参阅Neptune 与 Neo4j 的兼容性和重写 Cypher 查询以在 Neptune 上的 openCypher 中运行以了解更多信息。
支持 Neptune 中的子 openCypher 句
除非另有说明,否则 Neptune 支持以下子句:
MATCH
— 支持,除此之外
以及shortestPath()
目前不支持。allShortestPaths()
OPTIONAL MATCH
— 目前在 Neptune 中不支持。但是,Neptune 确实支持在MANDATORY MATCH
MATCH
查询中使用自定义 ID 值。-
RETURN
– 支持,但与SKIP
或LIMIT
的非静态值结合使用时除外。例如,以下内容目前不起作用:MATCH (n) RETURN n LIMIT toInteger(rand()) // Does NOT work!
-
WITH
– 支持,但与SKIP
或LIMIT
的非静态值结合使用时除外。例如,以下内容目前不起作用: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 值。
— 目前在 Neptune 中不支持。CALL[YIELD...]
UNION, UNION ALL
– 支持只读查询,但目前不支持突变查询。
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
日期和时间值可以从 "
dateT
time"
格式的字符串中解析,其中 date 和 time 都以下面支持的形式之一表示:
支持的日期格式
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
转换为 epochmillis
的 epochmillis()
函数。例如:
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 规范,因此您现在可以在CREATE
、MERGE
和子句中为节点和关系指定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 遇到多值属性,则任意选择其中一个值,从而产生不确定性的结果。