适用范围:
 NoSQL
重要
Azure Cosmos DB for NoSQL 全局辅助索引目前为预览版。 此预览版在提供时未使用服务级别协议。 目前,不建议对生产工作负荷使用全局辅助索引。 此预览版的某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款。
 
全局辅助索引提供了一种强大的方法来优化查询性能,并通过使用不同的分区键和/或数据模型存储数据来简化应用程序逻辑。 本文介绍如何创建全局辅助索引,以及如何使用这些索引来避免跨分区查询。
先决条件
启用全局辅助索引
为 Azure Cosmos DB 帐户启用全局辅助索引功能。 在启用全局辅助索引之前,必须为帐户启用连续备份。
登录到 Azure 门户。
 
转到你的 Azure Cosmos DB for NoSQL 帐户。
 
在资源菜单中,选择“设置”。
 
导航到“功能”页。 然后选择 NoSQL API 的全局辅助索引(预览版) 并 启用。
              
              
              
              
            
 
使用 Azure CLI,通过本机命令或 REST API 操作在 Azure Cosmos DB for NoSQL 帐户上启用全局辅助索引功能。
登录 Azure CLI。
az login
 
为现有 Azure Cosmos DB for NoSQL 帐户的资源组和帐户名称定义变量。
# Variable for resource group name
$resourceGroupName="<resource-group-name>"
# Variable for account name
$accountName="<account-name>"
# Variable for Azure subscription
$subscriptionId="<subscription-id>"
 
使用功能清单创建一个名为 capabilities.json 的新 JSON 文件。
{
  "properties": {
    "enableMaterializedViews": true
  }
}
注释
用于启用全局辅助索引的属性名称是 enableMaterializedViews以前的特征名称。 启用具体化视图将启用全局辅助索引。
 
 
获取帐户的标识符,并将其存储在名为 $accountId 的 shell 变量中。
$accountId="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.DocumentDB/databaseAccounts/$accountName"
 
使用 REST API 和 az rest,通过 HTTP PATCH 动词为账户启用预览全球二级索引功能。
az rest \
    --method PATCH \
    --uri "https://management.azure.com/$accountId/?api-version=2022-11-15-preview" \
    --body @capabilities.json
 
 
创建全局辅助索引
启用全局辅助索引功能后,可以创建全局辅助索引。
创建源容器
全局辅助索引存储源容器中的数据副本。 在创建全局辅助索引之前,请创建将从中生成索引容器的源容器。 如果 Azure Cosmos DB 帐户中已有要用作源的容器,则可以跳过这些步骤。
使用 Azure 门户、Azure SDK、Azure CLI 或 REST API 创建一个名为gsi-src的源容器,并将/customerId设为分区键路径。
注释
              /customerId 字段在本文中仅用作举例。 对于你自己的容器,请选择适用于你的解决方案的分区键。
 
 
在源容器中插入几个项。 要遵循本文中的示例,请确保项具有 customerId 和 emailAddress 字段。 示例项的外观可能类似于以下内容:
{
  "id": "eaf0338e-2b61-4163-822f-7bef75bf51de",
  "customerId": "36c7cc3d-1709-45c6-819f-10e5586a6cb7",
  "emailAddress": "justine@contoso.com",
  "name": "Justine"
}
小窍门
在此示例中,在添加索引容器之前,使用示例数据填充源容器。 还可以从空源容器创建全局辅助索引。
 
 
创建全局辅助索引容器
创建源容器后,可以使用 Azure 门户或 Azure CLI 创建全局辅助索引容器。
导航到 Azure Cosmos DB 帐户中的“数据资源管理器”。 在此示例中, gsi-src 选择源容器,然后从下拉列表中选择 “新建全局辅助索引 ”。
              
              
              
              
            
 
将为你填充源容器 ID。 在 “索引容器 ID ”字段中,输入 gsi-target。
 
在 “全局辅助索引定义 ”字段中,输入 SELECT c.customerId, c.emailAddress FROM c。
 
在 “分区”键 字段中,输入 /emailAddress。
              
              
              
              
            
 
全局辅助索引容器必须使用自动缩放吞吐量。 配置所需的任何其他容器设置,然后选择“ 确定 ”以创建全局辅助索引容器。
 
创建全局辅助索引容器后,数据会自动从源容器同步。 尝试在源容器中执行创建、更新和删除操作。 您会看到相同的更改被传播到全局辅助索引中的项目。
 
创建与源容器不同的分区键路径命名 gsi-target 的全局辅助索引。 对于此示例,请将 /emailAddress 指定为 gsi-target 容器的分区键路径。
为全局辅助索引创建定义清单,并将其保存在名为 gsi-definition.json的 JSON 文件中。 全局辅助索引容器必须使用自动缩放吞吐量。 在此阶段,还可以定义任何其他相关的容器属性,例如索引策略。
{
  "location": "West US 2",
  "tags": {},
  "properties": {
    "resource": {
      "id": "gsi-target",
      "partitionKey": {
        "paths": [
          "/emailAddress"
        ]
      },
      "materializedViewDefinition": {
        "sourceCollectionId": "gsi-src",
        "definition": "SELECT c.customerId, c.emailAddress FROM c"
      }
    },
    "options": {
      "autoscaleSettings": {
        "maxThroughput": 1000
      }
    }
  }
}        
 
重要
请注意,分区键路径设置为 /emailAddress.
定义全局辅助索引的属性是 materializedViewDefinition此功能的前一个名称。 定义 sourceCollectionId 源容器和 definition 包含用于确定索引容器的数据模型的查询。 创建全局辅助索引源容器和定义查询后无法更改。 详细了解 如何定义全局辅助索引 和查询约束。
 
 
接下来,进行 REST API 调用以创建 gsi-definition.json 文件中定义的全局辅助索引。 使用 Azure CLI 发出 REST API 调用。
为全局辅助索引和源数据库名称的名称创建变量:
# This should match the resource ID you defined in your json file
$gsiContainerName = "gsi-target"
# Database name for the source and index containers
$databaseName = "<Database that contains source container>"
# Azure Cosmos DB account name
$accountName = "<Azure Cosmos DB account name>"
# Resource name for your Azure Cosmos DB account
$resourceGroupName = "<Resource group for Azure Cosmos DB account>"
# Subscription id for your Azure Cosmos DB account
$subscriptionId = "<Subscription id>"
 
使用这些变量构造资源 ID。
$accountId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.DocumentDB/databaseAccounts/$accountName"
 
进行 REST API 调用以创建全局辅助索引:
az rest \
    --method PUT \
    --uri "https://management.azure.com$accountId/sqlDatabases/$databaseName/containers/$gsiContainerName/?api-version=2022-11-15-preview" \
    --body @gsi-definition.json \
    --headers content-type=application/json \
    --output json \
    --verbose
 
使用 REST API 检查全局辅助索引容器创建的状态:
az rest \
    --method GET \
    --uri "https://management.azure.com$accountId/sqlDatabases/$databaseName/containers/$gsiContainerName/?api-version=2022-11-15-preview" \
    --headers content-type=application/json \
    --query "{mvCreateStatus: properties.Status}"
 
 
创建全局辅助索引后,数据会自动从源容器同步。 尝试在源容器中执行创建、更新和删除操作。 您会看到相同的更改被传播到全局辅助索引中的项目。
 
 
从全局辅助索引查询数据
在此示例中,源容器按customerId进行分区,且全局辅助索引容器按emailAddress进行分区。 如果没有索引容器,则仅包含emailAddress的查询会是跨分区查询,但现在可以针对全局辅助索引运行,从而提高效率。
从全局辅助索引查询数据类似于从任何其他容器查询数据。 可以使用 Azure 门户、Azure SDK 或 REST API 查询全局辅助索引中的数据。
Container container = client.GetDatabase("gsi-db").GetContainer("gsi-target");
FeedIterator<MyClass> myQuery = container.GetItemQueryIterator<MyClass>(new QueryDefinition("SELECT * FROM c WHERE c.emailAddress = 'justine@contoso.com'"));
CosmosAsyncDatabase container = client.getDatabase("gsi-db");
CosmosAsyncContainer container = database.getContainer("gsi-target");
CosmosPagedFlux<MyClass> pagedFluxResponse = container.queryItems(
        "SELECT * FROM c WHERE c.emailAddress = 'justine@contoso.com'", null, MyClass.class);
const database = client.database("gsi-db");
const container = database.container("gsi-target");
const querySpec = {
    query: "SELECT * FROM c WHERE c.emailAddress = 'justine@contoso.com'"
 };
const { resources: items } = await container.items
    .query(querySpec)
    .fetchAll();
database = client.get_database_client("gsi-db")
container = database.get_container_client("gsi-target")
query = "SELECT * FROM c WHERE c.emailAddress = 'justine@contoso.com'"
container.query_items(
    query=query
)
gsiContainer, err := client.NewContainer("gsi-db", "gsi-target")
pager := gsiContainer.NewQueryItemsPager("select * from c where c.state = @state", azcosmos.NewPartitionKey(), &azcosmos.QueryOptions{
	QueryParameters: []azcosmos.QueryParameter{
		{
			Name:  "@state",
			Value: "Alaska",
		},
	},
})
if pager.More() {
  // Iterate through the results
  // page, _ := pager.NextPage(context.Background())
}
 
后续步骤