

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

# 如何在 Neptune 中處理 Gremlin 查詢
<a name="gremlin-explain-background-querying"></a>

在 Amazon Neptune 中，更複雜的周遊可由一系列模式表示，這些模式根據可跨模式共用的具名變數定義來建立關係，以建立聯結。如以下範例所示。

**問：什麼是頂點 `v1` 的雙躍點鄰近項？**

```
  Gremlin code:      g.V(‘v1’).out('knows').out('knows').path()
  Pattern:           (?1=<v1>, <knows>, ?2, ?) X Pattern(?2, <knows>, ?3, ?)

  The pattern produces a three-column relation (?1, ?2, ?3) like this:
                     ?1     ?2     ?3
                     ================
                     v1     v2     v3
                     v1     v2     v4
                     v1     v5     v6
```

透過在兩個模式之間共用 `?2` 變數 (在第一個模式中的 O 位置和第二個模式的 S 位置)，您可以建立從第一個躍點鄰近項到第二個躍點鄰近項的聯結。每個 Neptune 解決方案都有三個具名變數的繫結，可用來重新建立 [TinkerPop Traverser](http://tinkerpop.apache.org/docs/current/reference/#_the_traverser) (包括路徑資訊)。

```
```

Gremlin 查詢處理中的第一步就是將查詢剖析為 TinkerPop [Traversal](http://tinkerpop.apache.org/docs/current/reference/#traversal) 物件，此物件是由一系列 TinkerPop [步驟](http://tinkerpop.apache.org/docs/current/reference/#graph-traversal-steps)組成。這些步驟是開放原始碼 [Apache TinkerPop 專案](http://tinkerpop.apache.org/)的一部分，而且它們是在參考實作中構成 Gremlin 周遊的邏輯和實體運算子。它們都是用來代表查詢的模型。它們是可執行運算子，可根據所代表運算子的語意產生解決方案。例如，`.V()` 是由 TinkerPop [GraphStep](http://tinkerpop.apache.org/docs/current/reference/#graph-step) 表示及執行。

因為這些現成的 TinkerPop 步驟是可執行的，所以 TinkerPop 周遊可以執行任何 Gremlin 查詢並產生正確的答案。不過，針對大型圖形執行時，TinkerPop 步驟有時會非常低效率且速度緩慢。Neptune 不會使用它們，而是會嘗試將周遊轉換為由模式群組組成的宣告形式，如先前所述。

Neptune 目前在其原生查詢引擎中不支援所有 Gremlin 運算子 (步驟)。因此，它會嘗試盡可能將多個步驟摺疊成單一 `NeptuneGraphQueryStep`，其中包含所有已轉換步驟的宣告式邏輯查詢計畫。理想情況下，所有步驟都會進行轉換。但是，遇到無法轉換的步驟時，Neptune 會中斷原生執行，並延遲從該點一直到 TinkerPop 步驟的所有查詢執行。它不會嘗試將原生執行編入和編出。

在步驟轉換為邏輯查詢計劃之後，Neptune 會執行一系列查詢最佳化工具，根據靜態分析和估計基數來重寫查詢計畫。這些最佳化工具會執行如下動作：根據範圍計數重新排序運算子、刪除不必要或冗餘運算子、重新安排篩選條件、將運算子推送至不同的群組等等。

在產生最佳化的查詢計畫之後，Neptune 會建立實體運算子的管道，以執行查詢的工作。這包括從陳述式索引讀取資料、執行各種類型的聯結、篩選、排序等等。管道會產生解決方案串流，然後轉換回 TinkerPop Traverser 物件的串流。

## 查詢結果的序列化
<a name="gremlin-explain-background-querying-serialization"></a>

Amazon Neptune 目前倚賴 TinkerPop 回應訊息序列化程式，將查詢結果 (TinkerPop Traverser) 轉換為序列化資料，以透過線路傳回用戶端。這些序列化格式往往相當冗長。

例如，若要序列化頂點查詢的結果 (例如 `g.V().limit(1)`)，Neptune 查詢引擎必須執行單一搜尋來產生查詢結果。不過，`GraphSON` 序列化程式會執行大量的額外搜尋，將頂點封裝為序列化格式。它將必須執行一次搜尋以取得標籤、執行一次搜尋以取得屬性金鑰，以及針對頂點的每個屬性金鑰執行一次搜尋，以取得每個金鑰的所有值。

某些序列化格式更有效率，但都需要額外的搜尋。此外，TinkerPop 序列化程式不會嘗試避免重複的搜尋，通常會導致許多搜尋不必要地重複進行。

這使得編寫查詢非常重要，以便它們只特別要求其所需的資訊。例如，`g.V().limit(1).id()` 只會傳回頂點 ID 並消除所有其他序列化程式搜尋。[Neptune 中的 Gremlin `profile` API](gremlin-profile-api.md) 可讓您查看在查詢執行期間和序列化期間進行多少次搜尋呼叫。