共用方式為


管理 Azure Cosmos DB 中的索引編製原則

適用於:NoSQL

Azure Cosmos DB 會遵循針對每個容器所定義的索引編製原則來為資料編製索引。 新建立的容器所套用的預設索引編製原則,會對任何字串或數字強制執行範圍索引。 您可以使用自己的自訂索引編製原則來覆寫此原則。

注意

本文所述的索引編製原則更新方法僅適用於 Azure Cosmos DB for NoSQL。 了解 Azure Cosmos DB for MongoDB 中的索引編製,和 Azure Cosmos DB for Apache Cassandra 中的次要索引編製

索引編製原則範例

以下幾個範例說明以 JSON 格式顯示的索引編製原則。 它們會以 JSON 格式公開於 Azure 入口網站上。 透過 Azure CLI 或任何 SDK 也可以設定相同的參數。

可選擇性地排除一些屬性路徑的退出原則

{
    "indexingMode": "consistent",
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/path/to/single/excluded/property/?"
        },
        {
            "path": "/path/to/root/of/multiple/excluded/properties/*"
        }
    ]
}

可選擇性地納入一些屬性路徑的加入原則

{
    "indexingMode": "consistent",
    "includedPaths": [
        {
            "path": "/path/to/included/property/?"
        },
        {
            "path": "/path/to/root/of/multiple/included/properties/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/*"
        }
    ]
}

注意

一般建議您使用選擇退出索引編製原則。 Azure Cosmos DB 會主動為任何可能新增至資料模型的新屬性編製索引。

僅對特定屬性路徑使用空間索引

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        }
    ],
    "spatialIndexes": [
        {
                    "path": "/path/to/geojson/property/?",
            "types": [
                "Point",
                "Polygon",
                "MultiPolygon",
                "LineString"
            ]
        }
    ]
}

向量索引編製原則範例

除了包含或排除個別屬性的路徑以外,您也可以指定向量索引。 一般而言,每當使用 VectorDistance 系統函式來測量查詢向量與向量屬性之間的相似度時,都應該指定向量索引。

注意

在繼續之前,您必須啟用 Azure Cosmos DB NoSQL 向量索引和搜尋

重要

向量索引編製原則必須位於容器向量原則中定義的相同路徑。 深入了解容器向量原則

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        },
        {
            "path": "/vector/*"
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector",
            "type": "quantizedFlat"
        }
    ]
}

重要

已新增至索引編製原則的 "excludedPaths" 區段以確保插入效能最佳化的向量路徑。 若未將向量路徑新增至 "excludedPaths",將會導致向量插入的 RU 費用和延遲較高。

重要

目前,在建立之後,向量原則和向量索引是不可變的。 若要進行變更,請建立新的集合。

您可以定義下列類型的向量索引原則:

類型 描述 維度數上限
flat 將向量儲存在其他索引屬性的相同索引上。 505
quantizedFlat 量化 (壓縮) 向量,再儲存在索引上。 這樣可以改善延遲和輸送量,代價是精確度降低。 4096
diskANN 根據 DiskANN 建立索引,進行快速且有效率的近似搜尋。 4096

flatquantizedFlat 索引類型會在執行向量搜尋時,使用 Azure Cosmos DB 索引來儲存和讀取每個向量。 使用 flat 索引的向量搜尋是暴力密碼破解搜尋,且會產生 100% 精確性。 不過,扁平索引上的向量有 505 維度限制。

quantizedFlat 索引會將量化或壓縮向量儲存在索引上。 使用 quantizedFlat 索引的向量搜尋也是暴力密碼破解搜尋,但其精確度可能略低於 100%,因為向量在加入至索引之前會先量化。 不過,使用 quantized flat 的向量搜尋相較於 flat 索引上的向量搜尋,其延遲應該會較低、輸送量更高,且 RU 成本較少。 如果您要使用查詢篩選條件將向量搜尋的範圍縮小到相對較小的向量集,這是一個不錯的選項。

diskANN 索引是不同的索引,專門針對使用 DiskANN 的向量定義,這是由 Microsoft Research 開發的高效能向量索引演算法套件。 DiskANN 索引可提供一些最低的延遲、最高的每秒查詢 (QPS),以及高精確度的最低 RU 成本查詢。 不過,由於 DiskANN 是近似最近鄰項目 (ANN) 索引,因此精確度可能低於 quantizedFlatflat

diskANNquantizedFlat 索引可以採用選擇性的索引建置參數,可用來微調適用於每個近似近鄰向量索引的精確度與延遲取捨。

  • quantizationByteSize:設定產品量化的大小(以位元組為單位)。 Min=1,Default=dynamic (系統決定),Max=512。 設定這個較大的值可能會導致較高的精確度向量搜尋,代價是較高的 RU 成本和更高的延遲。 這同時 quantizedFlat 適用於和 DiskANN 索引類型。
  • indexingSearchListSize:設定在索引建置建構期間要搜尋的向量數目。 Min=10,Default=100,Max=500。 設定這個較大的值可能會導致較高的精確度向量搜尋,代價是較長的索引建置時間和更高的向量內嵌延遲。 DiskANN這僅適用於索引。

Tuple 索引編製原則範例

此範例索引編製原則會在 events.name 和 events.category 上定義 Tuple 索引

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {"path":"/*"}, 
        {"path":"/events/[]/{name,category}/?"} 
    ],
    "excludedPaths":[],
    "compositeIndexes":[]
}

上述索引用於下列查詢。

SELECT * 
FROM root r 
WHERE 
   EXISTS (SELECT VALUE 1 FROM ev IN r.events 
           WHERE ev.name = ‘M&M’ AND ev.category = ‘Candy’) 

複合式索引編製原則範例

除了包含或排除個別屬性的路徑以外,您也可以指定複合式索引。 若要為多個屬性執行具有 ORDER BY 子句的查詢,必須要有這些屬性的複合式索引。 如果查詢包含篩選條件以及多個屬性的排序,您可能需要多個複合式索引。

對於有多個篩選條件的查詢或同時有篩選條件和 ORDER BY 子句的查詢,複合式索引也會有效能優勢。

注意

在複合路徑上,只會對純量值編製索引,因此複合路徑有隱含的 /?。 複合路徑中不支援 /* 萬用字元。 請勿在複合路徑中指定 /?/*。 複合路徑也會區分大小寫。

針對 (name asc, age desc) 定義的複合式索引

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"descending"
            }
        ]
    ]
}

下列查詢需要 name 和 age 的複合式索引:

查詢 1:

SELECT *
FROM c
ORDER BY c.name ASC, c.age DESC

查詢 2:

SELECT *
FROM c
ORDER BY c.name DESC, c.age ASC

此複合式索引有利於下列查詢,並可將篩選條件最佳化:

查詢 #3:

SELECT *
FROM c
WHERE c.name = "Tim"
ORDER BY c.name DESC, c.age ASC

查詢 #4:

SELECT *
FROM c
WHERE c.name = "Tim" AND c.age > 18

針對 (name ASC, age ASC) 和 (name ASC, age DESC) 定義的複合式索引

您可以在相同的索引編製原則內定義多個複合式索引。

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"ascending"
            }
        ],
        [  
            {  
                "path":"/name",
                "order":"ascending"
            },
            {  
                "path":"/age",
                "order":"descending"
            }
        ]
    ]
}

針對 (name ASC, age ASC) 定義的複合式索引

指定順序是選擇性動作。 若未指定,將採用遞增順序。

{  
    "automatic":true,
    "indexingMode":"Consistent",
    "includedPaths":[  
        {  
            "path":"/*"
        }
    ],
    "excludedPaths":[],
    "compositeIndexes":[  
        [  
            {  
               "path":"/name"
            },
            {  
               "path":"/age"
            }
        ]
    ]
}

排除所有屬性路徑但讓索引編製保持作用狀態

存留時間 (TTL) 功能有作用,但不需要其他索引以將 Azure Cosmos DB 作為純粹索引鍵-值存放區的情況下,可以使用此原則。

{
    "indexingMode": "consistent",
    "includedPaths": [],
    "excludedPaths": [{
        "path": "/*"
    }]
}

無索引編製

此原則會關閉索引編製。 如果 indexingMode 設定為 none,您就無法在容器上設定 TTL。

{
    "indexingMode": "none"
}

更新索引編製原則

在 Azure Cosmos DB 中,您可以使用下列任何方法來更新索引編製原則:

  • 從 Azure 入口網站
  • 使用 Azure CLI
  • 使用 PowerShell
  • 使用其中一個 SDK

更新索引編製原則將會觸發索引的轉換。 您也可以從 SDK 追蹤此轉換的進度。

注意

當您更新索引編製原則時,對 Azure Cosmos DB 的寫入不會間斷。 深入了解索引編製轉換

重要

移除索引會立即生效,而新增索引需要一些時間,因為需要索引轉換。 將一個索引取代為另一個索引時 (例如,將單一屬性索引取代為複合式索引),請務必先新增新的索引,然後等候索引轉換完成,從索引編製原則中移除先前的索引。 否則,這會對查詢上一個索引的能力造成負面影響,並可能會中斷任何參考上一個索引的作用中工作負載。

使用 Azure 入口網站

Azure Cosmos DB 容器會將其索引編製原則儲存為 JSON 文件,並可直接在 Azure 入口網站中編輯。

  1. 登入 Azure 入口網站

  2. 建立新的 Azure Cosmos DB 帳戶或選取現有的帳戶。

  3. 開啟 [資料總管] 窗格,然後選取您要處理的容器。

  4. 選取 [調整與設定]

  5. 修改索引編製原則 JSON 文件,如這些範例所說明。

  6. 當完成時,選擇儲存

使用 Azure 入口網站管理索引編製

使用 Azure CLI

若要建立具有自訂索引編製原則的容器,請參閱使用 CLI 建立具有自訂索引原則的容器

使用 PowerShell

若要建立具有自訂索引編製原則的容器,請參閱使用 PowerShell 建立具有自訂索引原則的容器

使用 .NET SDK

.NET SDK v3 中的 ContainerProperties 物件會公開 IndexingPolicy 屬性,以供您變更 IndexingMode 以及新增或移除 IncludedPathsExcludedPaths。 如需詳細資訊,請參閱快速入門:適用於 .NET 的 Azure Cosmos DB for NoSQL 用戶端程式庫

// Retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync();
// Set the indexing mode to consistent
containerResponse.Resource.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
// Add an included path
containerResponse.Resource.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
// Add an excluded path
containerResponse.Resource.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/name/*" });
// Add a spatial index
SpatialPath spatialPath = new SpatialPath
{
    Path = "/locations/*"
};
spatialPath.SpatialTypes.Add(SpatialType.Point);
containerResponse.Resource.IndexingPolicy.SpatialIndexes.Add(spatialPath);
// Add a composite index
containerResponse.Resource.IndexingPolicy.CompositeIndexes.Add(new Collection<CompositePath> { new CompositePath() { Path = "/name", Order = CompositePathSortOrder.Ascending }, new CompositePath() { Path = "/age", Order = CompositePathSortOrder.Descending } });
// Update container with changes
await client.GetContainer("database", "container").ReplaceContainerAsync(containerResponse.Resource);

若要追蹤索引的轉換進度,請傳遞 RequestOptions 物件並將其 PopulateQuotaInfo 屬性設定為 true。 從 x-ms-documentdb-collection-index-transformation-progress 回應標頭擷取值。

// retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync(new ContainerRequestOptions { PopulateQuotaInfo = true });
// retrieve the index transformation progress from the result
long indexTransformationProgress = long.Parse(containerResponse.Headers["x-ms-documentdb-collection-index-transformation-progress"]);

當在建立新容器時定義自訂索引編製原則時,SDK V3 的 Fluent API 可讓您以簡潔且有效率的方式撰寫此定義:

await client.GetDatabase("database").DefineContainer(name: "container", partitionKeyPath: "/myPartitionKey")
    .WithIndexingPolicy()
        .WithIncludedPaths()
            .Path("/*")
        .Attach()
        .WithExcludedPaths()
            .Path("/name/*")
        .Attach()
        .WithSpatialIndex()
            .Path("/locations/*", SpatialType.Point)
        .Attach()
        .WithCompositeIndex()
            .Path("/name", CompositePathSortOrder.Ascending)
            .Path("/age", CompositePathSortOrder.Descending)
        .Attach()
    .Attach()
    .CreateIfNotExistsAsync();

使用 Java SDK

Java SDK 中的 DocumentCollection 物件會公開 getIndexingPolicy()setIndexingPolicy() 方法。 這些方法所管理的 IndexingPolicy 物件可讓您變更索引編製模式,以及新增或移除已納入和排除的路徑。 如需詳細資訊,請參閱快速入門:建置 Java 應用程式以管理 Azure Cosmos DB for NoSQL 資料

// Retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), null);
containerResponse.subscribe(result -> {
DocumentCollection container = result.getResource();
IndexingPolicy indexingPolicy = container.getIndexingPolicy();

// Set the indexing mode to consistent
indexingPolicy.setIndexingMode(IndexingMode.Consistent);

// Add an included path

Collection<IncludedPath> includedPaths = new ArrayList<>();
IncludedPath includedPath = new IncludedPath();
includedPath.setPath("/*");
includedPaths.add(includedPath);
indexingPolicy.setIncludedPaths(includedPaths);

// Add an excluded path

Collection<ExcludedPath> excludedPaths = new ArrayList<>();
ExcludedPath excludedPath = new ExcludedPath();
excludedPath.setPath("/name/*");
excludedPaths.add(excludedPath);
indexingPolicy.setExcludedPaths(excludedPaths);

// Add a spatial index

Collection<SpatialSpec> spatialIndexes = new ArrayList<SpatialSpec>();
Collection<SpatialType> collectionOfSpatialTypes = new ArrayList<SpatialType>();

SpatialSpec spec = new SpatialSpec();
spec.setPath("/locations/*");
collectionOfSpatialTypes.add(SpatialType.Point);
spec.setSpatialTypes(collectionOfSpatialTypes);
spatialIndexes.add(spec);

indexingPolicy.setSpatialIndexes(spatialIndexes);

// Add a composite index

Collection<ArrayList<CompositePath>> compositeIndexes = new ArrayList<>();
ArrayList<CompositePath> compositePaths = new ArrayList<>();

CompositePath nameCompositePath = new CompositePath();
nameCompositePath.setPath("/name");
nameCompositePath.setOrder(CompositePathSortOrder.Ascending);

CompositePath ageCompositePath = new CompositePath();
ageCompositePath.setPath("/age");
ageCompositePath.setOrder(CompositePathSortOrder.Descending);

compositePaths.add(ageCompositePath);
compositePaths.add(nameCompositePath);

compositeIndexes.add(compositePaths);
indexingPolicy.setCompositeIndexes(compositeIndexes);

// Update the container with changes

 client.replaceCollection(container, null);
});

若要在容器上追蹤索引轉換進度,請傳遞會要求填入配額資訊的 RequestOptions 物件。 從 x-ms-documentdb-collection-index-transformation-progress 回應標頭擷取值。

// set the RequestOptions object
RequestOptions requestOptions = new RequestOptions();
requestOptions.setPopulateQuotaInfo(true);
// retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), requestOptions);
containerResponse.subscribe(result -> {
    // retrieve the index transformation progress from the response headers
    String indexTransformationProgress = result.getResponseHeaders().get("x-ms-documentdb-collection-index-transformation-progress");
});

使用 Node.js SDK

Node.js SDK 中的 ContainerDefinition 介面會公開 indexingPolicy 屬性,以供您變更 indexingMode 以及新增或移除 includedPathsexcludedPaths。 如需詳細資訊,請參閱快速入門 - 適用於 Node.js 的 Azure Cosmos DB for NoSQL 用戶端程式庫

擷取容器的詳細資料:

const containerResponse = await client.database('database').container('container').read();

將索引編製模式設定為一致:

containerResponse.body.indexingPolicy.indexingMode = "consistent";

新增包含空間索引的內含路徑:

containerResponse.body.indexingPolicy.includedPaths.push({
    includedPaths: [
      {
        path: "/age/*",
        indexes: [
          {
            kind: cosmos.DocumentBase.IndexKind.Range,
            dataType: cosmos.DocumentBase.DataType.String
          },
          {
            kind: cosmos.DocumentBase.IndexKind.Range,
            dataType: cosmos.DocumentBase.DataType.Number
          }
        ]
      },
      {
        path: "/locations/*",
        indexes: [
          {
            kind: cosmos.DocumentBase.IndexKind.Spatial,
            dataType: cosmos.DocumentBase.DataType.Point
          }
        ]
      }
    ]
  });

新增排除的路徑:

containerResponse.body.indexingPolicy.excludedPaths.push({ path: '/name/*' });

更新具有變更的容器:

const replaceResponse = await client.database('database').container('container').replace(containerResponse.body);

若要追蹤容器的索引轉換進度,請傳遞將 populateQuotaInfo 屬性設定為 trueRequestOptions 物件。 從 x-ms-documentdb-collection-index-transformation-progress 回應標頭擷取值。

// retrieve the container's details
const containerResponse = await client.database('database').container('container').read({
    populateQuotaInfo: true
});
// retrieve the index transformation progress from the response headers
const indexTransformationProgress = replaceResponse.headers['x-ms-documentdb-collection-index-transformation-progress'];

新增複合式索引:

 console.log("create container with composite indexes");
  const containerDefWithCompositeIndexes = {
    id: "containerWithCompositeIndexingPolicy",
    indexingPolicy: {
      automatic: true,
      indexingMode: IndexingMode.consistent,
      includedPaths: [
        {
          path: "/*",
        },
      ],
      excludedPaths: [
        {
          path: '/"systemMetadata"/*',
        },
      ],
      compositeIndexes: [
        [
          { path: "/field", order: "ascending" },
          { path: "/key", order: "ascending" },
        ],
      ],
    },
  };
  const containerWithCompositeIndexes = (
    await database.containers.create(containerDefWithCompositeIndexes)
  ).container;

使用 Python SDK

在使用 Python SDK V3 時,容器設定會以字典的形式進行管理。 您可以從這個字典存取索引編製原則及其所有屬性。 如需詳細資訊,請參閱快速入門:適用於 Python 的 Azure Cosmos DB for NoSQL 用戶端程式庫

擷取容器的詳細資料:

containerPath = 'dbs/database/colls/collection'
container = client.ReadContainer(containerPath)

將索引編製模式設定為一致:

container['indexingPolicy']['indexingMode'] = 'consistent'

使用包含的路徑和空間索引來定義索引編製原則:

container["indexingPolicy"] = {

    "indexingMode":"consistent",
    "spatialIndexes":[
                {"path":"/location/*","types":["Point"]}
             ],
    "includedPaths":[{"path":"/age/*","indexes":[]}],
    "excludedPaths":[{"path":"/*"}]
}

使用排除的路徑來定義索引編製原則:

container["indexingPolicy"] = {
    "indexingMode":"consistent",
    "includedPaths":[{"path":"/*","indexes":[]}],
    "excludedPaths":[{"path":"/name/*"}]
}

新增複合式索引:

container['indexingPolicy']['compositeIndexes'] = [
                [
                    {
                        "path": "/name",
                        "order": "ascending"
                    },
                    {
                        "path": "/age",
                        "order": "descending"
                    }
                ]
                ]

更新具有變更的容器:

response = client.ReplaceContainer(containerPath, container)

下一步

在下列文章中深入了解編製索引: