

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

# 创建自定义 IAM 策略语句来访问 Amazon Neptune 中的数据
<a name="iam-data-access-policies"></a>

Neptune 数据访问策略语句使用[数据访问操作](iam-dp-actions.md)、[资源](iam-data-resources.md)和[条件键](iam-data-condition-keys.md#iam-neptune-condition-keys)，所有这些都以 `neptune-db:` 前缀开头。

**Topics**
+ [在 Neptune 数据访问策略语句中使用查询操作](#iam-data-query-actions)
+ [用于在 Amazon Neptune 中访问数据的 IAM 操作](iam-dp-actions.md)
+ [用于在 Amazon Neptune 中访问数据的 IAM 资源类型](iam-data-resources.md)
+ [用于在 Amazon Neptune 中访问数据的 IAM 条件键](iam-data-condition-keys.md)
+ [在 Amazon Neptune 中创建 IAM 数据访问策略](iam-data-access-examples.md)

## 在 Neptune 数据访问策略语句中使用查询操作
<a name="iam-data-query-actions"></a>

在数据访问策略语句中可以使用三个 Neptune 查询操作，即 `ReadDataViaQuery`、`WriteDataViaQuery` 和 `DeleteDataViaQuery`。特定的查询可能需要权限才能执行其中多个操作，而且可能并不总是很清楚必须允许这些操作的哪种组合才能运行查询。

在运行查询之前，Neptune 会确定运行每个查询步骤所需的权限，并将这些权限组合成查询所需的完整权限集。请注意，这组完整的权限包括查询*可能*执行的所有操作，这些操作不一定是查询在数据上运行时实际执行的一组操作。

这意味着，要允许给定的查询运行，必须针对该查询可能执行的每个操作提供权限，无论它是否实际执行这些操作。

以下是一些示例 Gremlin 查询，其中对此进行了更详细的解释：
+ 

  ```
  g.V().count()
  ```

  `g.V()` 和 `count()` 只需要读取权限，因此整个查询只需要 `ReadDataViaQuery` 访问权限。
+ 

  ```
  g.addV()
  ```

  在插入新顶点之前，`addV()` 需要检查具有给定 ID 的顶点是否存在。这意味着它同时需要 `ReadDataViaQuery` 和 `WriteDataViaQuery` 访问权限。
+ 

  ```
  g.V('1').as('a').out('created').addE('createdBy').to('a')
  ```

  `g.V('1').as('a')` 和 `out('created')` 只需要读取权限，但 `addE().from('a')` 同时需要读取和写入权限，因为在添加新边缘之前，`addE()` 需要读取 `from` 和 `to` 顶点并检查是否已经存在具有相同 ID 的边缘。因此，整个查询同时需要 `ReadDataViaQuery` 和 `WriteDataViaQuery` 访问权限。
+ 

  ```
  g.V().drop()
  ```

  `g.V()` 只需要读取访问权限。`drop()` 同时需要读取和删除访问权限，因为它需要在删除顶点或边缘之前读取顶点或边缘，因此查询总体同时需要 `ReadDataViaQuery` 和 `DeleteDataViaQuery` 访问权限。
+ 

  ```
  g.V('1').property(single, 'key1', 'value1')
  ```

  `g.V('1')` 只需要读取访问权限，但 `property(single, 'key1', 'value1')` 需要读取、写入和删除访问权限。在这里，如果键和值尚不存在于顶点中，则 `property()` 步骤会插入它们，但如果它们已经存在，则该步骤会删除现有的属性值并在其位置插入一个新值。因此，整个查询需要 `ReadDataViaQuery`、`WriteDataViaQuery` 和 `DeleteDataViaQuery` 访问权限。

  任何包含 `property()` 步骤的查询都需要 `ReadDataViaQuery`、`WriteDataViaQuery` 和 `DeleteDataViaQuery` 权限。

下面是一些 openCypher 示例：
+ 

  ```
  MATCH (n)
  RETURN n
  ```

  此查询读取数据库中的所有节点并返回它们，这只需要 `ReadDataViaQuery` 访问权限即可。
+ 

  ```
  MATCH (n:Person)
  SET n.dept = 'AWS'
  ```

  此查询需要 `ReadDataViaQuery`、`WriteDataViaQuery` 和 `DeleteDataViaQuery` 访问权限。它会读取所有标签为“Person”的节点，然后向它们添加一个带有键 `dept` 和值 `AWS` 的新属性，或者如果该 `dept` 属性已经存在，则删除旧值并改为插入 `AWS`。此外，如果要设置的值为 `null`，`SET` 会完全删除该属性。

   由于 `SET` 子句在某些情况下可能需要删除现有值，因此它**始终**需要 `DeleteDataViaQuery` 权限以及 `ReadDataViaQuery` 和 `WriteDataViaQuery` 权限。
+ 

  ```
  MATCH (n:Person)
  DETACH DELETE n
  ```

  此查询需要 `ReadDataViaQuery` 和 `DeleteDataViaQuery` 权限。它会找到所有带有标签 `Person` 的节点，并将它们以及连接到这些节点的边缘和任何关联的标签和属性一起删除。
+ 

  ```
  MERGE (n:Person {name: 'John'})-[:knows]->(:Person {name: 'Peter'})
  RETURN n
  ```

  此查询需要 `ReadDataViaQuery` 和 `WriteDataViaQuery` 权限。`MERGE` 子句要么匹配指定的模式，要么创建该模式。因为当模式不匹配时，可能会发生写入操作，因此需要写入权限以及读取权限。