在 Microsoft Fabric 中自定义 Cosmos DB 中的索引策略

Cosmos DB 中的索引旨在提供快速灵活的查询性能,无论数据如何发展。 本指南使用 Fabric 门户或 Azure SDK 修改容器的索引策略。

先决条件

  • 包含数据的现有容器

  • Python 3.12 或更高版本
  • Node.js 22 或更高版本
  • .NET SDK 9.0 或更高版本

使用 Fabric 门户进行设置

首先,使用 Fabric 门户设置容器的索引策略

  1. 打开 Fabric 门户(https://app.fabric.microsoft.com)。

  2. 导航到现有的 Cosmos DB 数据库。

  3. 选择并展开现有容器。 然后选择 “设置”。

  4. “设置” 部分中,选择“ 索引策略 ”选项卡。

    Fabric 门户中某个容器的“索引策略”部分的屏幕截图。

  5. 在编辑器中,将设置更新为新值。 例如,请考虑包含业务数据和系统元数据的此示例文档结构:

    {
      "id": "product-123",
      "_etag": "abc123def456",
      "name": "Wireless Headphones",
      "category": "Electronics",
      "price": 99.99,
      "metadata": {
        "createdBy": "system",
        "lastModified": "2025-10-30T10:30:00Z",
        "version": 1.2,
        "tags": ["internal", "generated"],
        "audit": {
          "importSource": "legacy-system",
          "reviewStatus": "pending"
        }
      }
    }
    
  6. 可以创建索引策略,该策略为查询中通常不使用的元数据字段之外的所有属性编制索引:

    {
      "indexingMode": "consistent",
      "automatic": true,
      "includedPaths": [
        {
          "path": "/*"
        }
      ],
      "excludedPaths": [
        {
          "path": "/_etag/?"
        },
        {
          "path": "/metadata/*"
        }
      ]
    }
    

    注释

    /_etag/? 路径使用 ? 来仅排除 _etag 属性本身,而 /metadata/* 使用 * 来排除整个 metadata 对象及其所有子属性。

    将此索引策略应用于示例文档:

    • 索引属性idnamecategoryprice(和其他所有属性除外)
    • 从索引中排除
      • _etag 属性 (单个值)
      • 包含其属性的整个metadata对象,包括 createdBylastModifiedversiontags和嵌套audit对象

    此方法通过排除通常不在用户查询中使用的系统元数据来优化存储和性能,同时保留所有业务数据可搜索。

使用 Azure SDK 进行设置

最后,使用 Azure SDK 设置容器的索引策略。

database = client.get_database_client("<database-name>")

container = database.get_container_client("<container-name>")

# Create policy that indexes all paths except metadata fields
indexing_policy = {
  "indexingMode": "consistent",
  "automatic": True,
  "includedPaths": [
    {
      "path": "/*"
    }
  ],
  "excludedPaths": [
    {
      "path": "/_etag/?"
    },
    {
      "path": "/metadata/*"
    }
  ]
}

# Apply the indexing policy to the container
await database.replace_container(container, partition_key=PartitionKey(path='/<partition-key-path>'), indexing_policy=indexing_policy)
const container: Container = client.database('<database-name>').container('<container-name>');

const { resource: containerProperties } = await container.read();

// Create policy that indexes all paths except metadata fields
containerProperties['indexingPolicy'] = {
  indexingMode: 'consistent',
  automatic: true,
  includedPaths: [
    {
      path: '/*'
    }
  ],
  excludedPaths: [
    {
      path: '/_etag/?'
    },
    {
      path: '/metadata/*'
    }
  ]
}

await container.replace(containerProperties);
Container container = client
    .GetDatabase("<database-name>")
    .GetContainer("<container-name>");

ContainerProperties properties = await container.ReadContainerAsync();

// Create policy that indexes all paths except metadata fields
IndexingPolicy indexingPolicy = new()
{
    IndexingMode = IndexingMode.Consistent,
    Automatic = true
};
indexingPolicy.IncludedPaths.Add(
    new IncludedPath { Path = "/*" }
);
indexingPolicy.ExcludedPaths.Add(
    new ExcludedPath{ Path = "/_etag/?" }
);
indexingPolicy.ExcludedPaths.Add(
    new ExcludedPath{ Path = "/metadata/*" }
);
properties.IndexingPolicy = indexingPolicy;

await container.ReplaceContainerAsync(properties);