

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon Neptune 中的 openCypher 延伸模組
<a name="access-graph-opencypher-extensions"></a>

 Amazon Neptune 支援 openCypher 規格參考第 9 版。如需詳細資訊，請參閱 Amazon Neptune [Amazon Neptune 中的 openCypher 規格合規](feature-opencypher-compliance.md)中的 。此外，Amazon Neptune 支援此處列出的功能。除非提及特定版本，否則這些功能可在 Neptune 資料庫和 Neptune Analytics 中使用。

## 查詢時間 S3 資料存取
<a name="opencypher-compliance-neptune-read"></a>

適用於 Neptune 資料庫 1.4.7.0 及更新版本。

Neptune 支援`neptune.read()`函數直接在 openCypher 查詢中從 Amazon S3 讀取 CSV 或 Parquet 資料。與在查詢之前匯入資料的大量載入器不同， 會在查詢執行時間`neptune.read()`存取 Amazon S3 資料。

如需完整的文件，請參閱 [neptune.read()](access-graph-opencypher-21-extensions-s3-read.md)。

## Neptune 特定 `join()` 函數
<a name="opencypher-compliance-join-function"></a>

可用於 Neptune 資料庫和 Neptune Analytics。

Neptune 實作一個不存在於 openCypher 規格中的 `join()` 函數。它從字串常值清單和字串分隔符號中建立一個字串常值。它需要兩個引數：
+ 第一個引數是字串常值的清單。
+ 第二個引數是分隔符號，它可以由零個、一個或多個字元組成。

範例：

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

## Neptune 特定 `removeKeyFromMap()` 函數
<a name="opencypher-compliance-removeKeyFromMap-function"></a>

可用於 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 值
<a name="opencypher-compliance-custom-ids"></a>

可用於 Neptune 資料庫 1.2.0.2 及更高版本，以及 Neptune Analytics。

從[引擎 1.2.0.2 版](engine-releases-1.2.0.2.md)開始，Neptune 已擴展 OpenCypher 規格，因此您現在可以在 `CREATE`、`MERGE` 和 `MATCH` 子句中指定節點和關係的 `id` 值。這可讓您指派易於使用的字串，而不是系統產生的 UUID 來識別節點和關係。

在 Neptune Analytics 中，自訂 ID 值不適用於邊緣。

**警告**  
OpenCypher 規格的這個延伸模組不與舊版相容，因為 `~id` 現在被視為保留的屬性名稱。如果您已在資料和查詢中使用 `~id` 做為屬性，則必須將現有屬性遷移至新的屬性索引鍵，並移除舊的屬性索引鍵。請參閱 [如果您目前使用 `~id` 做為屬性，該怎麼辦](#opencypher-compliance-custom-ids-migrating)。

以下範例展示如何建立具有自訂 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` 子句中使用自訂 ID 的範例：

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

### 如果您目前使用 `~id` 做為屬性，該怎麼辦
<a name="opencypher-compliance-custom-ids-migrating"></a>

使用[引擎 1.2.0.2 版](engine-releases-1.2.0.2.md)，OpenCypher 子句中的 `~id` 金鑰現在被視為 `id`，而不是做為一個屬性。這表示，如果您有一個名為 `~id` 的屬性，將無法存取它。

如果您使用的是 `~id` 屬性，則在升級至引擎版本 `1.2.0.2` 或更高版本之前必須做的事情，首先是將現有 `~id` 屬性遷移至新的屬性索引鍵，然後刪除 `~id` 屬性。例如，下面查詢：
+ 為所有節點建立一個名為 'newId' 的新屬性、
+ 將 '\$1id' 屬性的值複製到 'NewID' 屬性，
+ 然後從資料中刪除 '\$1id' 屬性

```
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 中的 CALL 子查詢支援
<a name="call-subquery-support"></a>

 可用於 Neptune 資料庫 1.4.1.0 及更新版本，以及 Neptune Analytics。

 Amazon 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 { ... }`會針對前面 MATCH 子句相符`friend`的每個 執行內部查詢部分。執行內部查詢時， `ORDER`和 `LIMIT`子句位於特定朋友居住城市的本機，因此我們為每個朋友取得兩個城市 （最多）。

 所有查詢子句都可在`CALL`子查詢中使用。這也包括巢狀`CALL`子查詢。第一個`WITH`子句和發出的變數存在某些限制，如下所述。

### CALL 子查詢內的變數範圍
<a name="variable-scope-inside-call-subquery"></a>

 來自子句的變數，在其中使用的`CALL`子查詢之前，必須由初始`WITH`子句匯入。與一般`WITH`子句不同，它只能包含變數清單，但不允許別名，且不能與 `DISTINCT`、`ORDER BY`、`WHERE`、 `SKIP`或 搭配使用`LIMIT`。

### 從 CALL 子查詢傳回的變數
<a name="variables-returned-call-subquery"></a>

 從`CALL`子查詢發出的變數會以最終 `RETURN` 子句指定。請注意，在`CALL`子查詢之前，發出的變數不能與變數重疊。

### 限制
<a name="call-subquery-limitations"></a>

 目前不支援`CALL`子查詢內的更新。

## Neptune openCypher 函數
<a name="opencypher-compliance-new-functions"></a>

 可用於 Neptune 資料庫 1.4.1.0 及更新版本，以及 Neptune Analytics。

**textIndexOf**

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

 傳回`lookup`從位移 `from`（包含） `text` 開始到位移 `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]
    }]
}
```

**collSubtract**

 `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]
    }]
}
```

**collIntersection**

 `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]
    }]
}
```

## 排序函數
<a name="sorting-functions"></a>

 下列各節定義要排序集合的函數。這些函數採用 （在某些情況下為選用） `config`映射引數，或定義排序索引鍵和/或排序方向的多個此類映射清單：

```
{ key: STRING, order: STRING }
```

 `key` 以下是對應或節點屬性，其值將用於排序。 分別`order`是 "`asc`" 或 "`desc`" （不區分大小寫） 來指定遞增或遞減排序。根據預設，排序會以遞增順序執行。

**collSort**

 `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"
          }
        }]
    }]
}
```

## 暫時函數
<a name="temporal-functions"></a>

 暫時函數可從 Neptune [1.4.5.0 ](https://docs.aws.amazon.com/releases/release-1.4.5.0.xml)版及更新版本取得。

### day
<a name="temporal-functions-day"></a>

 `day(temporal :: (datetime | date)) :: (LONG)` 

 從 `datetime`或 `date`值傳回當月`day`的 。對於 `datetime`：值會根據輸入標準化為 UTC，然後再擷取日期。對於 `date`：根據時區擷取日。

 `datetime` 輸入可在 Neptune 資料庫和 Neptune Analytics 中使用：

```
RETURN day(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "day(datetime('2021-06-03T01:48:14Z'))": 3
    }]
}
```

 在這裡， `datetime` 會標準化為 UTC，因此 \$108：00 會切換回 6 月 2 日。

```
RETURN day(datetime('2021-06-03T00:00:00+08:00'))
{
  "results": [{
      "day(datetime('2021-06-03T00:00:00+08:00'))": 2
    }]
}
```

 `date` 輸入僅適用於 Neptune Analytics：

```
RETURN day(date('2021-06-03Z'))
{
  "results": [{
      "day(date('2021-06-03Z'))": 3
    }]
}
```

 會`date`保留時區，並保留 6 月 3 日。

```
RETURN day(date('2021-06-03+08:00'))
{
  "results": [{
      "day(date('2021-06-03+08:00'))": 3
    }]
}
```

### month
<a name="temporal-functions-month"></a>

 `month(temporal :: (datetime | date)) :: (LONG)` 

 從 `datetime`或 `date`值 (1-12) 傳回月份。對於 `datetime`：在擷取月份之前，值會根據輸入標準化為 UTC。對於 `date`：根據時區擷取月份。

 `datetime` 輸入可在 Neptune 資料庫和 Neptune Analytics 中使用：

```
RETURN month(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "month(datetime('2021-06-03T01:48:14Z'))": 6
    }]
}
```

 在這裡， `datetime` 會標準化為 UTC，因此 \$108：00 會切換回 5 月 31 日。

```
RETURN month(datetime('2021-06-01T00:00:00+08:00'))
{
  "results": [{
      "month(datetime('2021-06-01T00:00:00+08:00'))": 5
    }]
}
```

 `date` 輸入僅適用於 Neptune Analytics：

```
RETURN month(date('2021-06-03Z'))
{
  "results": [{
      "month(date('2021-06-03Z'))": 6
    }]
}
```

 會`date`保留時區，並保留 6 月 1 日。

```
RETURN month(date('2021-06-01+08:00'))
{
  "results": [{
      "month(date('2021-06-01+08:00'))": 6
    }]
}
```

### year
<a name="temporal-functions-year"></a>

 `year(temporal :: (datetime | date)) :: (LONG)` 

 從 `datetime`或 `date`值傳回年份。對於 `datetime`：在擷取年份之前，根據輸入將值標準化為 UTC。對於 `date`：根據時區擷取年份。

 `datetime` 輸入可在 Neptune 資料庫和 Neptune Analytics 中使用：

```
RETURN year(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "year(datetime('2021-06-03T01:48:14Z'))": 2021
    }]
}
```

 在這裡， `datetime` 會標準化為 UTC，因此 \$108：00 會切換回 2020 年 12 月 31 日。

```
RETURN year(datetime('2021-01-01T00:00:00+08:00'))
{
  "results": [{
      "year(datetime('2021-01-01T00:00:00+08:00'))": 2020
    }]
}
```

 `date` 輸入僅適用於 Neptune Analytics：

```
RETURN year(date('2021-06-03Z'))
{
  "results": [{
      "year(date('2021-06-03Z'))": 2021
    }]
}
```

 會`date`保留時區，並保留 2021 年 6 月。

```
RETURN year(date('2021-01-01+08:00'))
{
  "results": [{
      "year(date('2021-01-01+08:00'))": 2021
    }]
}
```

### Neptune openCypher 函數
<a name="openCypher-functions"></a>

 可用於 Neptune 資料庫 1.4.6.0 及更高版本，以及 Neptune Analytics。

#### reduce()
<a name="openCypher-functions-reduce"></a>

 透過將每個清單元素與執行中總數或「累積器」結合，減少依序處理每個清單元素。從初始值開始，它會在每次操作後更新累積器，並在下一次反覆運算時使用該更新的值。

 `for i in (0, ..., n) acc = acc X list[I], where X denotes any binary operator` 

 處理完所有元素後，便會傳回最終累積結果。

 典型的 reduce() 結構為 - `reduce(accumulator = initial , variable IN list | expression)` 

**類型規格：**  
 `- initial: starting value for the accumulator :: (Long | FLOAT | STRING | LIST? OF (STRING, LONG, FLOAT)) - list: the input list :: LIST OF T where T matches initial type - variable :: represents each element in the input list - expression :: Only supports '+' and '*' operator - return :: Same type as initial ` 

**限制：**  
 目前，`reduce()`表達式僅支援 ：
+  數值乘法 
+  數值新增 
+  字串串連 
+  列出串連 

 它們由 `+`或 `*`運算子表示。表達式應為二進位表達式，如下所示 - `expression pattern: accumulator + any variable or accumulator * any variable` 

**溢位處理：**  
 Neptune 會在`reduce()`評估期間偵測數值溢位，並根據資料類型做出不同的回應：

```
LONG (signed 64‑bit)
--------------------
• Valid range: –9 223 372 036 854 775 808 … 9 223 372 036 854 775 807  
• If any intermediate or final value falls outside this range,
  Neptune aborts the query with long overflow error message.
  
FLOAT (IEEE‑754 double)
-----------------------
• Largest finite value ≈ 1.79 × 10^308  
• Larger results overflow to INF
  Once `INF` is produced, it propagates through the remainder
  of the reduction.
```

**範例：**  
如需 reduce() 函數，請參閱下列範例。

```
1. Long Addition:
RETURN reduce(sum = 0, n IN [1, 2, 3] | sum + n)
{
  "results": [{
      "reduce(sum = 0, n IN [1, 2, 3] | sum + n)": 6
    }]
}

2. String Concatenation:
RETURN reduce(str = "", x IN ["A", "B", "C"] | str + x) 
{
  "results": [{
      "reduce(str = "", x IN ["A", "B", "C"] | str + x)": "ABC"
    }]
}

3. List Combination:
RETURN reduce(lst = [], x IN [1, 2, 3] | lst + x)
{
  "results": [{
      "reduce(lst = [], x IN [1, 2, 3] | lst + x)": [1, 2, 3]
    }]
}

4. Float Addition:
RETURN reduce(total = 0.0, x IN [1.5, 2.5, 3.5] | total + x) 
{
  "results": [{
      "reduce(total = 0.0, x IN [1.5, 2.5, 3.5] | total + x)": 7.5
    }]
}

5. Long Multiplication:
RETURN reduce(product = 1, n IN [1, 2, 3] | product * n)
{
  "results": [{
      "reduce(product = 0, n IN [1, 2, 3] | product * n)": 6
    }]
}

6. Float Multiplication:
RETURN reduce(product = 1.0, n IN [1.5, 2.5, 3.5] | product * n)
{
  "results": [{
      "reduce(product = 1.0, n IN [1.5, 2.5, 3.5] | product * n)": 13.125
    }]
}

7. Long Overflow (Exception):
RETURN reduce(s = 9223372036854775807, x IN [2, 3] | s * x) AS result
{
"results": [{
    "reduce(s = 9223372036854775807, x IN [2, 3] | s * x) AS result": long overflow
    }]
}

8. Float Overflow:
RETURN reduce(s = 9.0e307, x IN [8.0e307, 1.0e307] | s + x) AS result
{
"results": [{
    "reduce(s = 9.0e307, x IN [8.0e307, 1.0e307] | s + x) AS result": INF
    }]
}
```