亚马逊 Neptune 中的 OpenCypher 扩展 - Amazon Neptune
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

亚马逊 Neptune 中的 OpenCypher 扩展

亚马逊 Neptune 支持 OpenCypher 规范参考版本 9。有关详情,亚马逊 Neptune 中符合 OpenCypher 规范请参阅 Amazon Neptune。此外,亚马逊 Neptune 支持此处列出的功能。除非提及特定版本,否则这些功能可在海王星数据库和海王星分析中使用。

Neptune 特定的 join() 函数

在 Neptune 数据库和 Neptune Analytics 中可用。

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

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

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

示例:

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

Neptune 特定的 removeKeyFromMap() 函数

在 Neptune 数据库和 Neptune Analytics 中可用。

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

此函数采用两个参数:

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

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

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

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

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

在 Neptune Database 1.2.0.2 及更高版本和 Neptune Analytics 中可用。

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

在 Neptune Analytics 中,自定义 ID 值不适用于边缘。

警告

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

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

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 中调用子查询支持

在 Neptune Database 1.4.1.0 及更高版本和 Neptune Analytics 中可用。

亚马逊 Neptune 支持CALL子查询。CALL子查询是主查询的一部分,对于CALL子查询的每个输入,它在隔离的范围内运行。

例如,假设图表包含有关人员、他们的朋友和他们居住的城市的数据。我们可以使用CALL子查询来检索某人的每个朋友居住的两个最大的城市:

MATCH (person:Person)-[:knows]->(friend) CALL { WITH friend MATCH (friend)-[:lived_in]->(city) RETURN city ORDER BY city.population DESC LIMIT 2 } RETURN person, friend, city

在此示例中,内部的查询部分CALL { ... }是针对与前面friend的 MATCH 子句匹配的每个子句执行的。执行内部查询时,and LIMIT 子句是特定朋友居住的城市的本地子句,因此(最多)每个朋友可以获得两个城市。ORDER

所有查询子句都可以在CALL子查询中使用。这也包括嵌套CALL子查询。第一个WITH子句和发出的变量存在一些限制,下面将对此进行说明。

CALL 子查询中变量的作用域

CALL子查询之前的子句中使用的变量必须由初始WITH子句导入。与常规WITH子句不同,它只能包含变量列表,但不允许别名,也不能与DISTINCT、、ORDER BYWHERESKIP、或LIMIT一起使用。

从 CALL 子查询返回的变量

CALL子查询中发出的变量由最后RETURN一个子句指定。请注意,发出的变量不能与CALL子查询之前的变量重叠。

限制

到目前为止,不支持CALL子查询内部的更新。

Neptune OpenCypher 函数

在 Neptune Database 1.4.1.0 及更高版本和 Neptune Analytics 中可用。

textIndexOf

textIndexOf(text :: STRING, lookup :: STRING, from = 0 :: INTEGER?, to = -1 :: INTEGER?) :: (INTEGER?)

返回text从偏移量from(含)到偏移量(不包括)的范围内首次出现的索引。lookup to如果to为 -1,则范围一直延续到末尾text。索引从零开始,以 Unicode 标量值(非代理代码点)表示。

RETURN textIndexOf('Amazon Neptune', 'e') { "results": [{ "textIndexOf('Amazon Neptune', 'e')": 8 }] }

collToSet

collToSet(values :: LIST OF ANY?) :: (LIST? OF ANY?)

返回一个仅包含原始列表中唯一元素的新列表。保持原始列表的顺序(例如[1, 6, 5, 1, 5]退货[1, 6, 5])。

RETURN collToSet([1, 6, 5, 1, 1, 5]) { "results": [{ "collToSet([1, 6, 5, 1, 1, 5])": [1, 6, 5] }] }

collSubtr

collSubtract(first :: LIST OF ANY?, second :: LIST OF ANY?) :: (LIST? OF ANY?)

返回一个新列表,其中包含从中first排除元素的所有唯一元素second

RETURN collSubtract([2, 5, 1, 0], [1, 5]) { "results": [{ "collSubtract([2, 5, 1, 0], [1, 5])": [0, 2] }] }

collInter

collIntersection(first :: LIST? OF ANY?, second :: LIST? OF ANY?) :: (LIST? OF ANY?)

返回一个包含first和交叉点的所有唯一元素的新列表second

RETURN collIntersection([2, 5, 1, 0], [1, 5]) { "results": [{ "collIntersection([2, 5, 1, 0], [1, 5])": [1, 5] }] }

排序函数

以下各节定义了对集合进行排序的函数。这些函数采用定义排序键和/或排序方向的config映射参数(在某些情况下是可选的)映射参数或多个此类映射的列表:

{ key: STRING, order: STRING }

以下key是地图或节点属性,其值将用于排序。 order分别为 “asc” 或 “desc”(不区分大小写),分别指定升序或降序排序。默认情况下,将按升序进行排序。

colsort

collSort(coll :: LIST OF ANY, config :: MAP?) :: (LIST? OF ANY?)

返回一个新的排序列表,其中包含coll输入列表中的元素。

RETURN collSort([5, 3, 1], {order: 'asc'}) { "results": [{ "collSort([5, 3, 1])": [1, 3, 5] }] }

collSortMaps

collSortMaps(coll :: LIST OF MAP, config :: MAP) :: (LIST? OF ANY?)

返回按指定key属性的值排序的地图列表。

RETURN collSortMaps([{name: 'Alice', age: 25}, {name: 'Bob', age: 35}, {name: 'Charlie', age: 18}], {key: 'age', order: 'desc'}) { "results": [{ "x": [{ "age": 35, "name": "Bob" }, { "age": 25, "name": "Alice" }, { "age": 18, "name": "Charlie" }] }] }

collSortMulti

collSortMulti(coll :: LIST OF MAP?, configs = [] :: LIST OF MAP, limit = -1 :: INTEGER?, skip = 0 :: INTEGER?) :: (LIST? OF ANY?)

返回按指定key属性的值排序的地图列表,可以选择应用限制和跳过。

RETURN collSortMulti([{name: 'Alice', age: 25}, {name: 'Bob', age: 35}, {name: 'Charlie', age: 18}], [{key: 'age', order: 'desc'}, {key:'name'}]) as x { "results": [{ "x": [{ "age": 35, "name": "Bob" }, { "age": 25, "name": "Alice" }, { "age": 18, "name": "Charlie" }] }] }

collSortNodes

collSortNodes(coll :: LIST OF NODE, config :: MAP) :: (LIST? OF NODE?)

返回coll输入列表的排序版本,按节点元素各自key属性的值对它们进行排序。

create (n:person {name: 'Alice', age: 23}), (m:person {name: 'Eve', age: 21}), (o:person {name:'Bob', age:25}) {"results":[]} match (n:person) with collect(n) as people return collSortNodes(people, {key: 'name', order: 'desc'}) { "results": [{ "collSortNodes(people, 'name')": [{ "~id": "e599240a-8c23-4337-8aa8-f603c8fb5488", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 21, "name": "Eve" } }, { "~id": "8a6ef785-59e3-4a0b-a0ff-389655a9c4e6", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 25, "name": "Bob" } }, { "~id": "466bc826-f47f-452c-8a27-6b7bdf7ae9b4", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 23, "name": "Alice" } }] }] } match (n:person) with collect(n) as people return collSortNodes(people, {key: 'age'}) { "results": [{ "collSortNodes(people, '^age')": [{ "~id": "e599240a-8c23-4337-8aa8-f603c8fb5488", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 21, "name": "Eve" } }, { "~id": "466bc826-f47f-452c-8a27-6b7bdf7ae9b4", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 23, "name": "Alice" } }, { "~id": "8a6ef785-59e3-4a0b-a0ff-389655a9c4e6", "~entityType": "node", "~labels": ["person"], "~properties": { "age": 25, "name": "Bob" } }] }] }