管理 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 向量索引預覽功能中註冊,才能在 Azure Cosmos DB for 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 |
flat
和 quantizedFlat
索引類型會在執行向量搜尋時,使用 Azure Cosmos DB 索引來儲存和讀取每個向量。 使用 flat
索引的向量搜尋是暴力密碼破解搜尋,且會產生 100% 精確性。 不過,扁平索引上的向量有 505
維度限制。
quantizedFlat
索引會將量化或壓縮向量儲存在索引上。 使用 quantizedFlat
索引的向量搜尋也是暴力密碼破解搜尋,但其精確度可能略低於 100%,因為向量在加入至索引之前會先量化。 不過,使用 quantized flat
的向量搜尋相較於 flat
索引上的向量搜尋,其延遲應該會較低、輸送量更高,且 RU 成本較少。 如果您要使用查詢篩選條件將向量搜尋的範圍縮小到相對較小的向量集,這是一個不錯的選項。
diskANN
索引是不同的索引,專門針對使用 DiskANN 的向量定義,這是由 Microsoft Research 開發的高效能向量索引演算法套件。 DiskANN 索引可提供一些最低的延遲、最高的每秒查詢 (QPS),以及高精確度的最低 RU 成本查詢。 不過,由於 DiskANN 是近似最近鄰項目 (ANN) 索引,因此精確度可能低於 quantizedFlat
或 flat
。
複合式索引編製原則範例
除了包含或排除個別屬性的路徑以外,您也可以指定複合式索引。 若要為多個屬性執行具有 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 入口網站中編輯。
登入 Azure 入口網站。
建立新的 Azure Cosmos DB 帳戶或選取現有的帳戶。
開啟 [資料總管] 窗格,然後選取您要處理的容器。
選取 [調整與設定]。
修改索引編製原則 JSON 文件,如這些範例所說明。
當完成時,選擇儲存。
使用 Azure CLI
若要建立具有自訂索引編製原則的容器,請參閱使用 CLI 建立具有自訂索引原則的容器。
使用 PowerShell
若要建立具有自訂索引編製原則的容器,請參閱使用 PowerShell 建立具有自訂索引原則的容器。
使用 .NET SDK
.NET SDK v3 中的 ContainerProperties
物件會公開 IndexingPolicy
屬性,以供您變更 IndexingMode
以及新增或移除 IncludedPaths
和 ExcludedPaths
。 如需詳細資訊,請參閱快速入門:適用於 .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
以及新增或移除 includedPaths
和 excludedPaths
。 如需詳細資訊,請參閱快速入門 - 適用於 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
屬性設定為 true
的 RequestOptions
物件。 從 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)
下一步
在下列文章中深入了解編製索引: