

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

# Amazon Neptune 中的原生 Gremlin 步骤支持
<a name="gremlin-step-support"></a>

如[调整 Gremlin 查询](gremlin-traversal-tuning.md)中所述，Amazon Neptune 引擎目前并不完全原生支持所有 Gremlin 步骤。当前支持分为四类：
+ [始终可以转换为原生 Neptune 引擎操作的 Gremlin 步骤](#gremlin-steps-always)
+ [在某些情况下可以转换为原生 Neptune 引擎操作的 Gremlin 步骤](#gremlin-steps-sometimes) 
+ [从不转换为原生 Neptune 引擎操作的 Gremlin 步骤](#gremlin-steps-never) 
+ [Neptune 中根本不支持的 Gremlin 步骤](#neptune-gremlin-steps-unsupported) 

## 始终可以转换为原生 Neptune 引擎操作的 Gremlin 步骤
<a name="gremlin-steps-always"></a>

只要满足以下条件，许多 Gremlin 步骤可以转换为原生 Neptune 引擎操作：
+ 在查询中，它们前面没有无法转换的步骤。
+ 它们的父步骤（如果有）可以转换。
+ 它们的所有子遍历（如果有）都可以转换。

如果满足这些条件，以下 Gremlin 步骤将始终转换为原生 Neptune 引擎操作：
+ [and( )](http://tinkerpop.apache.org/docs/current/reference/#and-step)
+ [as( )](http://tinkerpop.apache.org/docs/current/reference/#as-step)
+ [count( )](http://tinkerpop.apache.org/docs/current/reference/#count-step)
+ [E( )](http://tinkerpop.apache.org/docs/current/reference/#graph-step)
+ [emit( )](http://tinkerpop.apache.org/docs/current/reference/#emit-step)
+ [explain( )](http://tinkerpop.apache.org/docs/current/reference/#explain-step)
+ [group( )](http://tinkerpop.apache.org/docs/current/reference/#group-step)
+ [groupCount( )](http://tinkerpop.apache.org/docs/current/reference/#groupcount-step)
+ [identity( )](http://tinkerpop.apache.org/docs/current/reference/#identity-step)
+ [is( )](http://tinkerpop.apache.org/docs/current/reference/#is-step)
+ [key( )](http://tinkerpop.apache.org/docs/current/reference/#key-step)
+ [label( )](http://tinkerpop.apache.org/docs/current/reference/#label-step)
+ [limit( )](http://tinkerpop.apache.org/docs/current/reference/#limit-step)
+ [local( )](http://tinkerpop.apache.org/docs/current/reference/#local-step)
+ [loops( )](http://tinkerpop.apache.org/docs/current/reference/#loops-step)
+ [not( )](http://tinkerpop.apache.org/docs/current/reference/#not-step)
+ [or( )](http://tinkerpop.apache.org/docs/current/reference/#or-step)
+ [profile( )](http://tinkerpop.apache.org/docs/current/reference/#profile-step)
+ [properties( )](http://tinkerpop.apache.org/docs/current/reference/#properties-step)
+ [subgraph( )](http://tinkerpop.apache.org/docs/current/reference/#subgraph-step)
+ [until( )](http://tinkerpop.apache.org/docs/current/reference/#until-step)
+ [V( )](http://tinkerpop.apache.org/docs/current/reference/#graph-step)
+ [value( )](http://tinkerpop.apache.org/docs/current/reference/#value-step)
+ [valueMap( )](http://tinkerpop.apache.org/docs/current/reference/#valuemap-step)
+ [values( )](http://tinkerpop.apache.org/docs/current/reference/#values-step)

## 在某些情况下可以转换为原生 Neptune 引擎操作的 Gremlin 步骤
<a name="gremlin-steps-sometimes"></a>

在某些情况下，一些 Gremlin 步骤可以转换为原生 Neptune 引擎操作，但在其它情况下则不可以：
+ [addE( )](http://tinkerpop.apache.org/docs/current/reference/#addedge-step) – `addE()` 步骤通常可以转换为原生 Neptune 引擎操作，除非紧随其后的是包含遍历作为键的 `property()` 步骤。
+ [addV( )](http://tinkerpop.apache.org/docs/current/reference/#addvertex-step) – `addV()` 步骤通常可以转换为原生 Neptune 引擎操作，除非紧随其后的是包含遍历作为键的 `property()` 步骤，或者除非分配了多个标签。
+ [aggregate( )](http://tinkerpop.apache.org/docs/current/reference/#store-step) – `aggregate()` 步骤通常可以转换为原生 Neptune 引擎操作，除非该步骤用于子遍历，或者除非存储的值不是顶点、边缘、id、标签或属性值。

  在下面的示例中，未转换 `aggregate()`，因为它正在子遍历中使用：

  ```
  g.V().has('code','ANC').as('a')
       .project('flights').by(select('a')
       .outE().aggregate('x'))
  ```

  在此示例中，未转换 aggregate()，因为存储的内容是值的 `min()`：

  ```
  g.V().has('code','ANC').outE().aggregate('x').by(values('dist').min())
  ```
+ [barrier( )](http://tinkerpop.apache.org/docs/current/reference/#barrier-step) – `barrier()` 步骤通常可以转换为原生 Neptune 引擎操作，除非其后的步骤未被转换。
+ [cap( )](http://tinkerpop.apache.org/docs/current/reference/#cap-step) – 转换 `cap()` 步骤的唯一情况是当将它与 `unfold()` 步骤组合以返回顶点、边缘、id 或属性值聚合的展开版本时。在本例中，`cap()` 将进行转换，因为它后跟 `.unfold()`：

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport').unfold()
  ```

  但是，如果您移除 `.unfold()`，则不会转换 `cap()`：

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport')
  ```
+ [coalesce ()](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) [— 转换`coalesce()`步骤的唯一情况是它遵循食谱页面上推荐的 [Upsert 模式](http://tinkerpop.apache.org/docs/current/recipes/#element-existence)。TinkerPop ](http://tinkerpop.apache.org/docs/current/recipes/)不允许使用其它 coalesce() 模式。转换仅限于以下情况：所有子遍历都可以转换，它们都生成与输出相同的类型（顶点、边缘、id、值、键或标签），它们都遍历到一个新元素，并且它们不包含步骤 `repeat()`。
+ [constant( )](http://tinkerpop.apache.org/docs/current/reference/#constant-step) – 当前，只有在遍历的 `sack().by()` 部分中使用 constant() 步骤来分配常量值时，才会转换此步骤，如下所示：

  ```
  g.V().has('code','ANC').sack(assign).by(constant(10)).out().limit(2)
  ```
+ [cyclicPath( )](http://tinkerpop.apache.org/docs/current/reference/#cyclicpath-step) – `cyclicPath()` 步骤通常可以转换为原生 Neptune 引擎操作，除非该步骤与 `by()`、`from()` 或 `to()` 调制器结合使用。例如，在以下查询中，未转换 `cyclicPath()`：

  ```
  g.V().has('code','ANC').as('a').out().out().cyclicPath().by('code')
  g.V().has('code','ANC').as('a').out().out().cyclicPath().from('a')
  g.V().has('code','ANC').as('a').out().out().cyclicPath().to('a')
  ```
+ [drop( )](http://tinkerpop.apache.org/docs/current/reference/#drop-step) – `drop()` 步骤通常可以转换为原生 Neptune 引擎操作，除非在 `sideEffect(`) 或 `optional()` 步骤中使用该步骤。
+ [fold ()](http://tinkerpop.apache.org/docs/current/reference/#fold-step) — 只有两种情况可以转换 fold () 步骤，即在[TinkerPop 食谱页面](http://tinkerpop.apache.org/docs/current/recipes/)推荐的 [Upsert 模式](http://tinkerpop.apache.org/docs/current/recipes/#element-existence)中使用它时，以及`group().by()`在这样的上下文中使用它时：

  ```
  g.V().has('code','ANC').out().group().by().by(values('code', 'city').fold())
  ```
+  [has( )](http://tinkerpop.apache.org/docs/current/reference/#has-step) – 只要带有 `T` 的查询使用谓词 `P.eq`、`P.neq` 或 `P.contains`，`has()` 步骤通常可以转换为原生 Neptune 引擎操作。预计暗示 `P` 的这些实例的 `has()` 变体也要转换为原生格式，例如 `hasId('id1234')`，它等同于 `has(eq, T.id, 'id1234')`。
+ [id( )](http://tinkerpop.apache.org/docs/current/reference/#id-step) – 除非在属性上使用 `id()` 步骤，否则将转换该步骤，如下所示：

  ```
  g.V().has('code','ANC').properties('code').id()
  ```
+  [mergeE()](https://tinkerpop.apache.org/docs/current/reference/#mergeedge-step) – 如果参数（合并条件 `onCreate` 和 `onMatch`）恒定（`null`、常量 `Map`，或 `Map` 的 `select()`），则 `mergeE()` 步骤可以转换为原生 Neptune 引擎操作。[更新插入边缘](https://docs.amazonaws.cn//neptune/latest/userguide/gremlin-efficient-upserts.html#gremlin-upserts-edges)中的所有示例都可以进行转换。
+  [mergeV()](https://tinkerpop.apache.org/docs/current/reference/#mergevertex-step) – 如果参数（合并条件 `onCreate` 和 `onMatch`）恒定（`null`、常量 `Map`，或 `Map` 的 `select()`），则 mergeV() 步骤可以转换为原生 Neptune 引擎操作。[更新插入顶点](https://docs.amazonaws.cn//neptune/latest/userguide/gremlin-efficient-upserts.html#gremlin-upserts-vertices)中的所有示例都可以进行转换。
+ [order( )](http://tinkerpop.apache.org/docs/current/reference/#order-step) – `order()` 步骤通常可以转换为原生 Neptune 引擎操作，除非满足以下条件之一：
  + `order()` 步骤位于嵌套的子遍历中，如下所示：

    ```
    g.V().has('code','ANC').where(V().out().order().by(id))
    ```
  + 正在使用本地排序，例如使用 `order(local)`。
  + 正在 `by()` 调制中使用自定义比较器进行排序。一个例子是这样使用 `sack()`：

    ```
    g.withSack(0).
      V().has('code','ANC').
          repeat(outE().sack(sum).by('dist').inV()).times(2).limit(10).
          order().by(sack())
    ```
  + 同一个元素上有多个排序。
+ [project( )](http://tinkerpop.apache.org/docs/current/reference/#project-step) – `project()` 步骤通常可以转换为原生 Neptune 引擎操作，除非 `project()` 后面的 `by()` 语句数量与指定的标签数量不匹配，如下所示：

  ```
  g.V().has('code','ANC').project('x', 'y').by(id)
  ```
+ [range( )](http://tinkerpop.apache.org/docs/current/reference/#range-step) - 只有当相关范围的下限为零（例如 `range(0,3)`）时，才会转换 `range()` 步骤。
+ [repeat( )](http://tinkerpop.apache.org/docs/current/reference/#repeat-step) – `repeat()` 步骤通常可以转换为原生 Neptune 引擎操作，除非它嵌套在另一个 `repeat()` 步骤中，如下所示：

  ```
  g.V().has('code','ANC').repeat(out().repeat(out()).times(2)).times(2)
  ```
+ [sack( )](http://tinkerpop.apache.org/docs/current/reference/#sack-step) – `sack()` 步骤通常可以转换为原生 Neptune 引擎操作，但以下情况除外：
  + 如果使用的是非数字 sack 运算符。
  + 如果使用的是 `+`、`-`、`mult`、`div`、`min` 和 `max` 以外的数字 sack 运算符。
  + 如果在 `where()` 步骤中使用 `sack()` 来根据 sack 值进行筛选，如下所示：

    ```
    g.V().has('code','ANC').sack(assign).by(values('code')).where(sack().is('ANC'))
    ```
+ [sum( )](http://tinkerpop.apache.org/docs/current/reference/#sum-step) – `sum()` 步骤通常可以转换为原生 Neptune 引擎操作，但在用于计算全局求和时则不可转换，如下所示：

  ```
  g.V().has('code','ANC').outE('routes').values('dist').sum()
  ```
+ [union( )](http://tinkerpop.apache.org/docs/current/reference/#union-step) – `union()` 步骤可以转换为原生 Neptune 引擎操作，只要它是查询中除最终步骤之外的最后一步。
+ [unfold ()](http://tinkerpop.apache.org/docs/current/reference/#unfold-step) — 只有在[食谱](http://tinkerpop.apache.org/docs/current/recipes/)页面推荐的 [Upsert 模式中使用该`unfold()`](http://tinkerpop.apache.org/docs/current/recipes/#element-existence)步骤时，以及将其与以下内容一起`cap()`使用时，才能将其转换为原生 Neptune 引擎操作：TinkerPop

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport').unfold()
  ```
+ [where( )](http://tinkerpop.apache.org/docs/current/reference/#where-step) – `where()` 步骤通常可以转换为原生 Neptune 引擎操作，但以下情况除外：
  + 当使用 by() 调制时，如下所示：

    ```
    g.V().hasLabel('airport').as('a')
         .where(gt('a')).by('runways')
    ```
  + 当使用 `eq`、`neq`、`within` 和 `without` 以外的比较运算符时。
  + 当使用用户提供的聚合时。

## 从不转换为原生 Neptune 引擎操作的 Gremlin 步骤
<a name="gremlin-steps-never"></a>

Neptune 支持以下 Gremlin 步骤，但它们从不转换为原生 Neptune 引擎操作。相反，它们由 Gremlin 服务器执行。
+ [choose( )](http://tinkerpop.apache.org/docs/current/reference/#choose-step)
+ [coin( )](http://tinkerpop.apache.org/docs/current/reference/#coin-step)
+ [inject( )](http://tinkerpop.apache.org/docs/current/reference/#inject-step)
+ [match( )](http://tinkerpop.apache.org/docs/current/reference/#match-step)
+ [math( )](http://tinkerpop.apache.org/docs/current/reference/#math-step)
+ [max( )](http://tinkerpop.apache.org/docs/current/reference/#max-step)
+ [mean( )](http://tinkerpop.apache.org/docs/current/reference/#mean-step)
+ [min( )](http://tinkerpop.apache.org/docs/current/reference/#min-step)
+ [option( )](http://tinkerpop.apache.org/docs/current/reference/#option-step)
+ [optional( )](http://tinkerpop.apache.org/docs/current/reference/#optional-step)
+ [path( )](http://tinkerpop.apache.org/docs/current/reference/#path-step)
+ [propertyMap( )](http://tinkerpop.apache.org/docs/current/reference/#propertymap-step)
+ [sample( )](http://tinkerpop.apache.org/docs/current/reference/#sample-step)
+ [skip( )](http://tinkerpop.apache.org/docs/current/reference/#skip-step)
+ [tail( )](http://tinkerpop.apache.org/docs/current/reference/#tail-step)
+ [timeLimit( )](http://tinkerpop.apache.org/docs/current/reference/#timelimit-step)
+ [tree( )](http://tinkerpop.apache.org/docs/current/reference/#tree-step)

## Neptune 中根本不支持的 Gremlin 步骤
<a name="neptune-gremlin-steps-unsupported"></a>

Neptune 根本不支持以下 Gremlin 步骤。在大多数情况下，这是因为它们需要 `GraphComputer`，而 Neptune 目前不支持。
+ [connectedComponent( )](http://tinkerpop.apache.org/docs/current/reference/#connectedcomponent-step)
+ [io( )](http://tinkerpop.apache.org/docs/current/reference/#io-step)
+ [shortestPath( )](http://tinkerpop.apache.org/docs/current/reference/#shortestpath-step)
+ [withComputer( )](http://tinkerpop.apache.org/docs/current/reference/#with-step)
+ [pageRank( )](http://tinkerpop.apache.org/docs/current/reference/#pagerank-step)
+ [peerPressure( )](http://tinkerpop.apache.org/docs/current/reference/#peerpressure-step)
+ [program( )](http://tinkerpop.apache.org/docs/current/reference/#program-step)

实际上，`io()` 步骤得到了部分支持，因为它可以用来从 URL 进行 `read()`，但不用来 `write()`。