

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

# 索引和搜索
<a name="indexing_search"></a>

Amazon Cloud Directory 支持两种索引方法：基于值和基于类型。基于值的索引是最常见的形式。使用这种索引，您可以根据对象属性的值，在目录中索引和搜索对象。使用基于类型的索引，您可以根据对象类型，在目录中索引和搜索对象。分面有助于定义对象类型。有关架构和分面的更多信息，请参阅[Schemas](schemas.md)和[Facets](schemas_whatarefacets.md)。

通过 Cloud Directory 中的索引可根据对象的属性值或分面值简单列出其他对象。每个索引在创建时都定义为与特定命名属性或分面结合使用。例如，可在“Person”分面的“email”属性上定义索引。索引是一类对象，这意味着客户端可以根据应用程序逻辑的需要灵活地创建、修改、列出和删除它们。

从概念上说，索引类似于带有子级的节点，会根据索引属性来标记指向索引节点的链接，而不是在附加子级时给定标签。但是，索引链接不是父–子关系的边缘，有自己的一组枚举 API 操作。

务必知道的是，Cloud Directory 中的索引不像其他系统中那样自动填充，而是使用 API 调用直接将对象附加到索引或从索引分离对象。虽然这样做会增加一些工作量，但允许您灵活地定义不同的索引范围。例如，您可以定义一个只跟踪特定节点的直接子级的索引。或者，您可以定义索引来跟踪本地根目录中给定分支内的所有对象，如某一部门的所有节点，您可以同时执行这两个任务。

**Topics**
+ [索引生命周期](indexing_search_lifecycle.md)
+ [基于分面的索引](indexing_search_facet.md)
+ [唯一索引与不唯一索引](indexing_search_unique.md)

# 索引生命周期
<a name="indexing_search_lifecycle"></a>

您可以使用以下 API 调用帮助开发索引的生命周期。

1. 您可以用 `[CreateIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_CreateIndex.html)` API 调用创建索引。您提供一个索引定义结构，用于描述该索引要跟踪的附加对象的属性。该定义还指明索引是否应强制唯一性。结果是新索引的对象 ID，应其像其他任何对象一样立即附加到层次结构中。例如，这可以是专用于保存索引的分支。

1. 用 `[AttachToIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_AttachToIndex.html)` API 调用将对象手动附加到索引。然后，该索引会自动跟踪每个附加对象的已定义属性的值。

1. 要使用索引以更具效率地枚举搜索对象，请调用 `[ListIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_ListIndex.html)` 并指定您感兴趣的值范围。

1. 使用 `[ListAttachedIndices](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_ListAttachedIndices.html)` API 调用来枚举附加到给定对象的索引。

1. 使用 `[DetachFromIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_DetachFromIndex.html)` API 调用手动从索引中删除对象。

1. 从索引中分离所有对象之后，可以使用 `[DeleteObject](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_DeleteObject.html)` API 调用删除该索引。

除了对所有对象使用的空间进行限制外，对目录中的索引数没有任何限制。索引及其附件确实会占用空间，但与节点和父-子链接所占用的空间相似。对于可以附加到给定对象的索引数有限制。有关更多信息，请参阅 [Amazon Cloud Directory 限制](limits.md)。

# 基于分面的索引
<a name="indexing_search_facet"></a>

通过基于分面的索引和搜索，您可以只搜索目录的子集，从而优化目录搜索。为此，您可以使用架构*分面*。例如，您不必在目录中的所有用户对象上进行搜索，而是可以只搜索包含员工分面的用户对象。这可以有效地帮助减少查询延迟时间以及所检索的数据量。

使用基于分面的索引，您可以使用 Cloud Directory 索引 API 操作来创建并将索引附加到对象的分面。您还可以列出索引结果，然后根据特定分面筛选这些结果。这可以将搜索范围缩小到只包含特定类型分面的对象，从而有效地缩短查询时间和数据量。

用于 `“facets”` 和 `[CreateIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_CreateIndex.html)` API 调用的 `[ListIndex](https://docs.aws.amazon.com/clouddirectory/latest/APIReference/API_ListIndex.html)` 属性，覆盖应用到对象的分面集合。此属性仅可用于 `CreateIndex` 和 `ListIndex` API 调用。如以下示例代码中所示，架构 ARN 使用目录的区域、所有者账户和目录 ID 来引用 Cloud Directory 架构。此服务提供的架构不显示在列表中。

```
String cloudDirectorySchemaArn = String.format(“arn:aws:clouddirectory:%s:%s:directory/%s/schema/CloudDirectory/1.0", region, ownerAccount, directoryId);
```

例如，以下示例代码创建基于分面的索引，特定于您的 AWS 账户和目录，您可以枚举使用分面 `SalesDepartmentFacet` 创建的所有对象。

**注意**  
请确保在以下所示参数中使用“facets”值。示例代码所示的 “facets” 实例引用了由 Cloud Directory 服务提供和控制的值。您可以将这些用于索引，但只能具有只读访问权限。

```
// Create a facet-based index
String cloudDirectorySchemaArn = String.format(“arn:aws:clouddirectory:%s:%s:directory/%s/schema/CloudDirectory/1.0",
    region, ownerAccount, directoryId);

facetIndexResult = clouddirectoryClient.createIndex(new CreateIndexRequest() 
  .withDirectoryArn(directoryArn) 
  .withOrderedIndexedAttributeList(List(new AttributeKey()     
        .withSchemaArn(cloudDirectorySchemaArn)     
        .withFacetName("facets")     
        .withName("facets"))) 
        .withIsUnique(false) 
        .withParentReference("/") 
        .withLinkName("MyFirstFacetIndex"))
facetIndex = facetIndexResult.getObjectIdentifier()

// Attach objects to the facet-based index
clouddirectoryClient.attachToIndex(new AttachToIndexRequest().withDirectoryArn(directoryArn)
  .withIndexReference(facetIndex).withTargetReference(userObj))

// List all objects
val listResults = clouddirectoryClient.listIndex(new ListIndexRequest()
  .withDirectoryArn(directoryArn)
  .withIndexReference(facetIndex)
  .getIndexAttachments()

// List the index results filtering for a certain facet
val filteredResults = clouddirectoryClient.listIndex(new ListIndexRequest()
  .withDirectoryArn(directoryArn)
  .withIndexReference(facetIndex)
  .withRangesOnIndexedValues(new ObjectAttributeRange()
    .withAttributeKey(new AttributeKey()
      .withFacetName("facets")
      .withName("facets")
      .withSchemaArn(cloudDirectorySchemaArn))
    .withRange(new TypedAttributeValueRange()
      .withStartMode(RangeMode.INCLUSIVE)
      .withStartValue("MySchema/1.0/SalesDepartmentFacet")
      .withEndMode(RangeMode.INCLUSIVE)
      .withEndValue("MySchema/1.0/SalesDepartmentFacet")
    )))
```

# 唯一索引与不唯一索引
<a name="indexing_search_unique"></a>

唯一索引不同于不唯一索引，其差别在于对附加到索引的对象实施索引属性值的唯一性。例如，您可能将 Person 对象填充到两个索引中，唯一索引是“email”属性，不唯一索引是“lastname”属性。lastname 索引允许多个 Person 对象附加到相同的姓氏。另一方面，`AttachToIndex` 调用目标，如果某个 Person 已经附加了相同的 email 属性，在 email 索引返回 `LinkNameAlreadyInUseException` 错误。请注意，错误不会删除 Person 对象本身。因此，应用程序可以创建 Person，并在一个批处理请求中将其附加到层次结构和其附加到索引。这可以确保如果任何索引违反了唯一性，对象及其全部附件将自动回滚。