

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

# Amazon Neptune 中的 SPARQL 標準合規
<a name="feature-sparql-compliance"></a>

在列出適用的 SPARQL 標準之後，以下各節提供有關 Neptune 的 SPARQL 實作如何擴展或從這些標準分出來的特定詳細資料。

**Topics**
+ [SPARQL 的適用標準](#feature-sparql-applicable-standards)
+ [Neptune SPARQL 中的預設命名空間字首](#sparql-default-prefixes)
+ [SPARQL 預設圖形和具名圖形](#sparql-default-graph)
+ [Neptune 支援的 SPARQL XPath 建構子函數](#access-graph-sparql-xpath-constructors)
+ [查詢和更新的預設基礎 IRI](#opencypher-compliance-default-iri)
+ [Neptune 中的 xsd:dateTime 值](#access-graph-sparql-xsd-date-time)
+ [特殊浮點值的 Neptune 處理](#feature-overview-special-values-comparisons)
+ [Neptune 任意長度值的限制](#feature-overview-arbitrary-length-values)
+ [Neptune 擴充 SPARQL 中的等於比較](#feature-overview-sparql-not-equal)
+ [處理 Neptune SPARQL 中超出範圍的常值](#feature-overview-sparql-out-of-range)

Amazon Neptune 在實作 SPARQL 圖形查詢語言時符合下列標準。

## SPARQL 的適用標準
<a name="feature-sparql-applicable-standards"></a>
+ SPARQL 是依 2013 年 3 月 21 日的 W3C [SPARQL 1.1 查詢語言](https://www.w3.org/TR/sparql11-query/)建議定義。
+ SPARQL 更新協定和查詢語言是依 W3C [SPARQL 1.1 更新](https://www.w3.org/TR/sparql11-update/)規格定義。
+ 對於數值格式，SPARQL 遵循 [W3C XML 結構描述定義語言 (XSD) 1.1 第 2 部分：Datatypes](https://www.w3.org/TR/xmlschema11-2/) 規格，其與 IEEE 754 規格一致 ([IEEE 754-2019 - 浮點數運算的 IEEE 標準](https://standards.ieee.org/content/ieee-standards/en/standard/754-2019.html)；如需詳細資訊，另請參閱 [Wikipedia IEEE 754 頁面](https://en.wikipedia.org/wiki/IEEE_754))。不過，此規格不包含於 `IEEE 754-1985` 版本後引入的功能。

## Neptune SPARQL 中的預設命名空間字首
<a name="sparql-default-prefixes"></a>

Neptune 定義下列 SPARQL 查詢預設使用的字首。如需詳細資訊，請參閱 SPARQL 規格中的 [Prefixed Names](https://www.w3.org/TR/sparql11-query/#prefNames)。
+ `rdf`  – `http://www.w3.org/1999/02/22-rdf-syntax-ns#`
+ `rdfs` – `http://www.w3.org/2000/01/rdf-schema#`
+ `owl`  – `http://www.w3.org/2002/07/owl#`
+ `xsd`  – `http://www.w3.org/2001/XMLSchema#`

## SPARQL 預設圖形和具名圖形
<a name="sparql-default-graph"></a>

Amazon Neptune 會將每個三元組與一個具名圖形建立關聯。預設圖形是定義成所有具名圖形的聯集。

**查詢的預設圖形**  
若您提交 SPARQL 查詢而未透過 `GRAPH` 關鍵字或 `FROM NAMED` 之類的建構式明確指定圖形，Neptune 一律會考慮資料庫執行個體中的所有三元組。例如，以下查詢將從 Neptune SPARQL 端點傳回所有三元組：

`SELECT * WHERE { ?s ?p ?o }`

顯現於多個圖形中的三元組將僅傳回一次。

如需預設圖形規格的相關資訊，請參閱 SPARQL 1.1 查詢語言規格的 [RDF 資料集](https://www.w3.org/TR/sparql11-query/#rdfDataset)一節。

**指定具名圖形以進行載入、插入或更新**  
如果您在載入、插入或更新三元組時未指定具名圖形，Neptune 會使用由 URI `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph` 定義的備用具名圖形。

當您使用三元組類型的格式發出 Neptune `Load` 請求時，可使用 `parserConfiguration: namedGraphUri` 參數指定具名圖形以用於所有三元組。如需 `Load` 命令語法的相關資訊，請參閱 [Neptune 載入器命令](load-api-reference-load.md)。

**重要**  
 若您既沒有使用此參數也未指定具名圖形，則將使用備用 URI：`http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`。

如果透過 `SPARQL UPDATE` 載入三元組而未明確提供具名圖形目標，則亦將使用上述的備用具名圖形。

您可以使用四元組格式的 N-Quads，為資料庫中的每個三元組指定具名圖形。

**注意**  
使用 N-Quads 允許您將具名圖形留空不填。在此情況下即會使用 `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`。  
您可以使用 `namedGraphUri` 剖析器組態選項，覆寫 N-Quads 的預設具名圖形。

## Neptune 支援的 SPARQL XPath 建構子函數
<a name="access-graph-sparql-xpath-constructors"></a>

SPARQL 標準允許 SPARQL 引擎支援一組可擴展的 XPath 建構子函數。Neptune 目前支援以下建構子函數，其中 `xsd` 字首定義為 `http://www.w3.org/2001/XMLSchema#`：
+ `xsd:boolean`
+ `xsd:integer`
+ `xsd:double`
+ `xsd:float`
+ `xsd:decimal`
+ `xsd:long`
+ `xsd:unsignedLong`

## 查詢和更新的預設基礎 IRI
<a name="opencypher-compliance-default-iri"></a>

因為 Neptune 叢集具有數個不同的端點，所以在解析相對 IRI 時，使用查詢或更新的請求 URL 做為基礎 IRI 可能會產生非預期的結果。

從[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)開始，如果明確的基礎 IRI 不是請求的一部分，Neptune 會使用 `http://aws.amazon.com/neptune/default/` 做為基礎 IRI。

在以下請求中，基礎 IRI 是請求的一部分：

```
BASE <http://example.org/default/>
INSERT DATA { <node1> <id> "n1" }

BASE <http://example.org/default/>
SELECT * { <node1> ?p ?o }
```

結果將是：

```
?p                                                   ?o
http://example.org/default/id                        n1
```

不過，在此請求中，不包括基礎 IRI：

```
INSERT DATA { <node1> <id> "n1" }

SELECT * { <node1> ?p ?o }
```

在此情況下，結果將是：

```
?p                                                   ?o
http://aws.amazon.com/neptune/default/id             n1
```

## Neptune 中的 xsd:dateTime 值
<a name="access-graph-sparql-xsd-date-time"></a>

基於效能考量，Neptune 一律會將日期/時間值儲存為國際標準時間 (UTC)。這能讓直接比較很有效率。

這也表示如果您輸入指定特定時區的 `dateTime` 值，Neptune 就會將值轉換為 UTC 並捨棄該時區資訊。接下來，當您收到 `dateTime` 後，該執會以 UTC 呈現而非原始時區的時間，而且您也無法再判斷原始時區。

## 特殊浮點值的 Neptune 處理
<a name="feature-overview-special-values-comparisons"></a>

Neptune 處理 SPARQL 特殊浮點值的方式如下。

### Neptune 中的 SPARQL NaN 處理
<a name="feature-overview-NaN-comparisons"></a>

在 Neptune 中，SPARQL 可以接受查詢中的 `NaN` 值。signalling 和 quiet `NaN` 值之間沒有任何區別。Neptune 會將所有 `NaN` 值視為 quiet。

在語意上，不可能進行 `NaN` 的比較，因為沒有任何值大於、小於或等於 `NaN`。這表示理論上，比較一端的 `NaN` 值和另一端的「任何內容」**永遠不相符。

 不過，[XSD 規格](https://www.w3.org/TR/xmlschema-2/#double)確實將兩個 `xsd:double` 或 `xsd:float` `NaN` 值視為相等。對於 `IN` 篩選條件、篩選條件表達式的等於運算子，以及完全相符語義 (在三重模式的物件位置中具有 `NaN`)，Neptune 皆遵循此原則。

### Neptune 中的 SPARQL 無限值處理
<a name="feature-overview-infinity-comparisons"></a>

在 Neptune 中，SPARQL 可接受查詢中的 `INF` 或 `-INF` 值。`INF` 會相比為大於任何其他數值，而 `-INF` 會相比為小於任何其他數值。

比較具有相符符號的兩個 INF 值時，無論其類型如何皆彼此相等 (例如，float `-INF` 等於 double `-INF`)。

當然，因為沒有任何值大於、小於或等於 `NaN`，所以不可能和 `NaN` 比較。

### Neptune 中的 SPARQL 負零處理
<a name="feature-overview-zero-comparisons"></a>

Neptune 會將負零值標準化為不帶正負號的零。負零值可用於查詢中，但不會原樣記錄在資料庫中，而且不等於不帶正負號的零。

## Neptune 任意長度值的限制
<a name="feature-overview-arbitrary-length-values"></a>

Neptune 將 SPARQL 中的 XSD 整數、浮點數和小數值的儲存大小限制在 64 位元。使用較大的值會導致 `InvalidNumericDataException` 錯誤。

## Neptune 擴充 SPARQL 中的等於比較
<a name="feature-overview-sparql-not-equal"></a>

SPARQL 標準為值運算式定義了三元邏輯，其中，值運算式可評估為 `true`、`false` 或 `error`。[SPARQL 1.1 規格](https://www.w3.org/TR/sparql11-query/#func-RDFterm-equal)中定義的術語相等性的預設語義適用於 `FILTER` 條件中的 `=` 與 `!=` 比較，這會在比較規格中[運算子資料表](https://www.w3.org/TR/sparql11-query/#OperatorMapping)中未明確比較的資料類型時產生一個 `error`。

這種行為可能會導致不直觀的結果，如下列範例所示。

資料：

```
<http://example.com/Server/1> <http://example.com/ip> "127.0.0.1"^^<http://example.com/datatype/IPAddress>
```

查詢 1：

```
SELECT * WHERE {
    <http://example.com/Server/1> <http://example.com/ip> ?o .
    FILTER(?o = "127.0.0.2"^^<http://example.com/datatype/IPAddress>)
}
```

查詢 2：

```
SELECT * WHERE {
    <http://example.com/Server/1> <http://example.com/ip> ?o .
    FILTER(?o != "127.0.0.2"^^<http://example.com/datatype/IPAddress>)
}
```

透過 Neptune 在 1.0.2.1 版本以前所使用的預設 SPARQL 語義，這兩個查詢都會傳回空結果。原因是 `?o = "127.0.0.2"^^<http://example.com/IPAddress>` 在評估 `?o := "127.0.0.1"^^<http://example.com/IPAddress>` 時會產生 `error`，而不是 `false`，因為沒有為自訂資料類型 `<http://example.com/IPAddress>` 指定明確的比較規則。因此，第二個查詢中的否定版本也會產生 `error`。在這兩個查詢中，`error` 會導致篩選出候選解決方案。

從 1.0.2.1 版開始，Neptune 已根據規格擴展 SPARQL 不等式運算子。請參閱 [SPARQL 第 1.1 節，運算子可擴充性](https://www.w3.org/TR/sparql11-query/#operatorExtensibility)，讓引擎定義如何跨使用者定義和不可比較內建資料類型進行比較的其他相關規則。

使用此選項，如果常值和資料類型在語法上相等，則 Neptune 會立即將在運算子對應表中未明確定義的任何兩個資料類型的比較視同評估為 `true`，否則為 false。任何情況下都不會發生 `error`。

使用這些新的語意，第二個查詢就會傳回 `"127.0.0.1"^^<http://example.com/IPAddress>`，而不是空的結果。

## 處理 Neptune SPARQL 中超出範圍的常值
<a name="feature-overview-sparql-out-of-range"></a>

XSD 語義會定義每個數值類型的值空間，但 `integer` 和 `decimal` 除外。這些定義會將每種類型限制在某個範圍的值內。例如，範圍 `xsd:byte` 的範圍為 -128 到 \$1127 (頭尾皆含)。任何超出此範圍的值都視為無效。

如果您嘗試在某類型的值空間外指派常值 (例如，嘗試將 `xsd:byte` 設為 999 的常值)，Neptune 會接受此超出範圍值的原樣，但不會四捨五入或截斷。但因為指定的類型不能代表此值，所以不會保存為數值。

也就是說，即使 `"999"^^xsd:byte` 是已定義之 `xsd:byte` 值範圍外的值，Neptune 也會接受它。但是，在資料庫中保存該值之後，此值只能用於三重模式物件位置的完全相符語義。因為超出範圍的常值不被視為數值，所以不會對其執行任何範圍篩選。

SPARQL 1.1 規格會以格式 `numeric`*-operator-*`numeric`、`string`*-operator-*`string`、`literal`*-operator-*`literal` 等等定義[範圍運算子](https://www.w3.org/TR/sparql11-query/#OperatorMapping)。Neptune 無法執行如 `invalid-literal`*-operator-*`numeric-value` 之類的範圍比較運算子。