Cosmos DB 是一个与架构无关的数据库,可用于循环访问应用程序,而无需处理架构或索引管理。 Microsoft Fabric 中的 Cosmos DB 中的索引旨在提供快速灵活的查询性能,无论数据如何发展。 在 Fabric 中的 Cosmos DB 中,每个容器都有一个索引策略,用于指示容器项的索引编制方式。 新创建的容器的默认索引策略为每个项的每个属性编制索引,并对任何字符串或数字强制使用范围索引。 此默认配置允许你获得良好的查询性能,而无需提前考虑索引和索引管理。
在某些情况下,可能需要替代此自动行为,以更好地满足需求。 可以通过自定义容器的索引策略来设置索引模式,并决定是否包含或排除属性路径。
索引模式
Cosmos DB 支持两种索引模式:
一致:创建、更新或删除项时,索引将以同步方式更新。
无:针对该容器禁用索引。 将容器用作单纯的键-值存储时,通常会使用此模式,在此情况下无需使用辅助索引。 它还可用于改善批量操作的性能。 批量操作完成后,可以将索引模式设置为
Consistent,然后使用 SDK 中的IndexTransformationProgress功能进行监控,直到完成。
注释
Cosmos DB 还支持延迟索引模式。 延迟索引在引擎未执行任何其他工作时,以较低的优先级对索引执行更新。 此行为可能会导致查询结果 不一致 或 不完整 。 如果计划查询 Cosmos DB 容器,则不应选择延迟索引。 新容器无法选择延迟索引。
索引大小
在 Cosmos DB 中,消耗的总存储是数据大小和索引大小的组合。 下面是索引大小的一些特点:
索引大小取决于索引策略。 如果所有属性都已编制索引,则索引大小可能会大于数据大小。
当删除数据时,索引将近乎连续地进行压缩。 但是,对于较小的数据删除,你可能不会立即观察到索引大小的减小。
物理分区拆分时,索引大小可能会暂时增大。 索引空间将在分区拆分完成后释放。
当容器的索引模式为“一致”时,系统属性
id和_ts始终被索引。系统属性
id和_ts未包含在容器策略的索引路径说明中。 此排除设计是刻意为之,因为这些系统属性默认总是会被索引,此行为不能被禁用。
注释
分区键(除非也是 /id)未在索引中,并且应包括在索引中。
包含和排除属性路径
自定义索引策略可以指定要在索引编制中显式包含或排除的属性路径。 通过优化已编制索引的路径数,可以显著减少写入操作的延迟和 RU 费用。
请再次考虑这个 JSON 项目:
{
"locations": [
{ "country": "Germany", "city": "Berlin" },
{ "country": "France", "city": "Paris" }
],
"headquarters": { "country": "Belgium", "employees": 250 },
"exports": [
{ "city": "Moscow" },
{ "city": "Athens" }
]
}
此索引策略会导致以下索引路径:
| 路径 | 价值 |
|---|---|
/locations/0/country |
"Germany" |
/locations/0/city |
"Berlin" |
/locations/1/country |
"France" |
/locations/1/city |
"Paris" |
/headquarters/country |
"Belgium" |
/headquarters/employees |
250 |
/exports/0/city |
"Moscow" |
/exports/1/city |
"Athens" |
这些路径是使用以下添加项定义的:
指向标量值(字符串或数字)的路径以
/?结尾数组中的元素通过
/[]表示法一起寻址(而不是/0、/1等)。可以使用
/*通配符来匹配节点下的任意元素
示例项的基线索引策略可能包括以下优化:
headquarters的employees路径是/headquarters/employees/?locations的country路径是/locations/[]/country/?headquarters下的任何内容的路径是/headquarters/*
例如,可以包含 /headquarters/employees/? 路径。 此路径确保为 employees 属性编制索引,但不会为此属性中的其他嵌套 JSON 编制索引。
包含/排除策略
任何索引策略必须包含根路径 /* 作为包含或排除的路径。
包含根路径可以选择性地排除不需要编制索引的路径。 建议使用此方法,因为它允许 Cosmos DB 主动为可能添加到模型的任何新属性编制索引。
排除根路径可以选择性地包含需要编制索引的路径。 默认情况下,分区键属性路径未使用排除的策略编制索引,并在需要时应显式包含。
对于包含常规字符(包括字母数字字符和下划线 _)的路径,无需在双引号中转义路径字符串(例如 "/path/?")。 对于包含其他特殊字符的路径,需要在双引号中转义路径字符串(例如 "/"path-abc"/?")。 如果预期路径中会出现特殊字符,出于安全考虑,可以转义每个路径。 在功能上,转义每个路径还是仅转义包含特殊字符的路径没有任何差别。
默认情况下,系统属性
_etag被排除在索引之外,除非将 etag 添加到索引所包含的路径中。如果将索引模式设为“一致”,则会自动为系统属性 和
id编制索引。如果项中不存在显式索引路径,则会向索引添加一个值以指示该路径未定义。
所有显式包含的路径都会将值添加到容器中每个项的索引,即便该路径未为给定项定义。
有关详细信息,请参阅 示例索引策略。
包含/排除优先级
如果包含路径和排除路径有冲突,则以更精确的路径优先。
请看以下示例:
包含的路径:
/food/ingredients/nutrition/*排除的路径:
/food/ingredients/*
在这种情况下,包含路径优先于排除路径,因为它更精确。 根据这些路径,位于/food/ingredients路径或嵌套在该路径中的任何数据都将从索引中排除。 异常是包含的路径 /food/ingredients/nutrition/* 中的数据,该路径将被索引。
下面是 Cosmos DB 中包括和排除的路径优先级的一些规则:
深度较大的路径比宽度较小的路径更精确。 例如:
/a/b/?比/a/?更精确。/?比/*更精确。 例如,/a/?比它/a/*更精确,因此/a/?优先。路径
/*必须是包含路径或排除路径。
全文索引
全文 索引能够通过索引高效地实现全文搜索和评分。 通过在索引策略中添加包含要编制索引的所有文本路径的 fullTextIndexes 部分,可轻松定义全文路径。 例如:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
},
],
"fullTextIndexes": [
{
"path": "/text"
}
]
}
重要
全文索引策略必须位于在容器的全文策略中定义的路径上。 有关详细信息,请参阅 全文搜索。
矢量索引
矢量索引可在使用 系统函数执行矢量搜索时提高效率VECTORDISTANCE。 在应用向量索引时,矢量搜索的延迟较低、吞吐量越高,请求单位(RU)消耗量更少。 可以指定以下类型的矢量索引策略:
| 类型 | DESCRIPTION | 最大维度 |
|---|---|---|
flat |
将向量存储在与其他已索引属性相同的索引上。 | 505 |
quantizedFlat |
在索引上存储之前,量化(压缩)矢量。 此类型可以通过牺牲少量精度来改善延迟和吞吐量。 | 4096 |
diskANN |
基于 DiskANN 创建索引,实现快速高效的近似搜索。 | 4096 |
重要
创建后,矢量策略和矢量索引是不可变的。 若要进行更改,请创建新的集合。
请注意以下几点:
flat和quantizedFlat类型的索引使用 Cosmos DB 的索引在矢量搜索期间存储和读取每个向量。 具有flat索引的矢量搜索是暴力搜索,可提供 100% 的准确性或召回率。 这种准确性意味着搜索始终在数据集中找到最相似的向量。 但是,索引flat支持最多具有505维度的向量。quantizedFlat索引在该索引上存储量化(压缩)矢量。 使用quantizedFlat索引的矢量搜索也是暴力搜索,但由于矢量在添加到索引之前进行了量化,因此其准确度可能略低于 100%。 但相较于quantized flat索引上的矢量搜索,使用flat的矢量搜索应会具有更低的延迟、更高的吞吐量和更低的 RU 成本。 对于使用查询筛选器将矢量搜索缩小到相对较小的矢量集的方案,此类型是一个不错的选择。 在此方案中,需要高准确度。diskANN索引是专门为应用 DiskANN 的矢量定义的单独索引,DiskANN 是 Microsoft Research 开发的高性能矢量索引算法套件。 DiskANN 索引可提供一些延迟最低、吞吐量最高且 RU 成本最低的查询,同时仍保持较高的准确度。 但由于 DiskANN 是近似最近邻域 (ANN) 索引,因此准确度可能低于quantizedFlat或flat。diskANN和quantizedFlat索引可以采用可选的索引生成参数,这些参数可用于优化适用于每个近似最近邻矢量索引的准确度与延迟权衡。
quantizationByteSize:设置产品量化的大小(以字节为单位)。 (Min=1,Default=dynamic(系统决定),Max=512) 设置此大小越大,可能会导致更高的准确度矢量搜索,代价是 RU 成本更高,延迟更高。 此权衡适用于这两种quantizedFlat类型和DiskANN索引类型。-
indexingSearchListSize:设置在构建索引期间要搜索的矢量数。 最小值为 10,默认值为 100,最大值为 500。 设置此大小越大,可能会导致更高的准确度矢量搜索,代价是索引生成时间更长,矢量引入延迟越高。DiskANN此特征仅适用于索引。
-
下面是带有矢量索引的索引创建策略示例:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?",
},
{
"path": "/vector/*"
}
],
"vectorIndexes": [
{
"path": "/vector",
"type": "diskANN"
}
]
}
重要
应将向量路径添加到 excludedPaths 索引策略的节,以确保优化插入性能。 不添加向量路径 excludedPaths 会导致矢量插入的 RU 费用和延迟增高。
矢量索引策略还必须位于容器的向量策略中定义的路径上。 有关详细信息,请参阅 矢量策略。
空间索引
在索引策略中定义空间路径时,应定义要将哪个索引 type 应用到该路径。
空间索引的可能类型包括:
点
多边形
MultiPolygon
线串
默认情况下,Cosmos DB 不会创建任何空间索引。 若要使用空间 SQL 内置函数,请在所需的属性上创建空间索引。 有关详细信息,请参阅 空间索引。
元组索引
在数组元素中的多个字段上执行筛选时,元组索引很有用。 元组索引是使用元组说明符 []在索引策略的 includedPaths 节中定义的。
注释
与指定包含或排除路径不同,不能创建包含 /* 通配符的路径。 每个元组路径都需要以 /? 结束。 如果项中不存在元组路径中的元组,则会向索引中添加一个值,以指示元组未定义。
数组元组路径在 includedPaths 节中使用以下表示法定义:<path prefix>/[]/{<tuple 1>, <tuple 2>, …, <tuple n>}/?
请考虑以下关于数组元组的重要规则:
元组的每个部分都用逗号分隔。
路径前缀的第一部分是元组之间共有的路径。 它是从根目录到数组的路径。 在我们的示例中,它是
/events。在第一部分之后,元组应包括数组通配符说明符
[]。 所有数组元组路径都应在元组说明符之前具有数组通配符说明符{}。下一部分使用元组说明符
{}指定元组。元组需要使用与其他索引路径相同的路径规范,但有一些例外情况:
元组不应以
/作为开头。元组不应包含数组通配符。
元组不应以
?或*.?是元组路径中的最后一段,应在元组说明符段之后立即指定。
例如,此规范是有效的元组路径:/events/[]/{name, category}/?
下面是数组元组路径的一些更为有效的示例:
[
{ "path": "/events/[]/{name/first, name/last}/?" },
{ "path": "/events/[]/{name/first, category}/?" },
{ "path": "/events/[]/{name/first, category/subcategory}/?" },
{ "path": "/events/[]/{name/[1]/first, category}/?" },
{ "path": "/events/[]/{[1], [3]}/?" },
{ "path": "/city/[1]/events/[]/{name, category}/?" }
]
下面是一些无效的数组元组路径的示例,并附有说明:
| 无效路径 | 说明 |
|---|---|
/events/[]/{name/[]/first, category}/? |
其中一个元组具有数组通配符 |
/events/[]/{name, category}/* |
数组元组路径中的最后一段应 ? 不是 * |
/events/[]/{{name, first},category}/? |
元组说明符是嵌套的 |
/events/{name, category}/? |
元组说明符前缺少数组通配符 |
/events/[]/{/name,/category}/? |
元组必须以 / 开头 |
/events/[]/{name/?,category/?}/? |
元组必须以 ? 结束 |
/city/[]/events/[]/{name, category}/? |
路径前缀为两个数组通配符 |
组合索引
包含 ORDER BY 子句(该子句包含两个或更多个属性)的查询需要一个组合索引。 还可以定义一个组合索引来改善许多相等性和范围查询的性能。 默认情况下,未定义复合索引,因此应根据需要添加复合索引。
不能在 /* 复合索引路径中使用通配符。 每个复合路径会自动以 /? 结尾,因此你无需额外添加。 复合路径必须指向标量值,这是复合索引中唯一包含的值。 如果项中不存在复合索引路径或指向非标值,Cosmos DB 会将一个值添加到索引中,以显示路径未定义。
定义复合索引时,请指定以下两个组件:
以特定顺序定义的两个或多个属性路径,影响复合索引的使用方式。
顺序,定义为 升序 或 降序。
添加复合索引时,查询会利用现有范围索引,直到新的复合索引添加完成。 因此,在添加组合索引时,可能不会立即观察到性能改进。
小窍门
可以使用其中一个软件开发工具包(SDK)跟踪索引转换的进度。
对多个属性的 ORDER BY 查询:
对包含 ORDER BY 子句(该子句包含两个或更多个属性)的查询使用组合索引时,请注意以下事项。
如果组合索引路径与
ORDER BY子句中的属性顺序不匹配,则组合索引无法支持查询。组合索引路径的顺序(升序或降序)还应与
order子句中的ORDER BY相匹配。组合索引还支持在所有路径中使用反向顺序的
ORDER BY子句。
考虑以下示例,其中针对属性 name、age 和 _ts 定义了组合索引:
| 复合索引 | 示例 ORDER BY 查询 |
受复合索引支持吗? |
|---|---|---|
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age asc |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.age ASC, c.name asc |
No |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name DESC, c.age DESC |
Yes |
(name ASC, age ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age DESC |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC, timestamp ASC |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c ORDER BY c.name ASC, c.age ASC |
No |
应该自定义索引策略,以便可为所有必要的 ORDER BY 查询提供服务。
包含针对多个属性的筛选器的查询
如果查询包含针对两个或更多个属性的筛选器,为这些属性创建组合索引可能会有帮助。
例如,请考虑以下同时包含相等性筛选器和范围筛选器的查询:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND c.age > 18
如果能够对 (name ASC, age ASC)请求单位(RU)应用复合索引,则此查询的效率更高,花费更少的时间和消耗更少的请求单位。
具有多个范围筛选器的查询也可使用组合索引进行优化。 不过,每个单独的组合索引只能优化一个范围筛选器。 范围筛选器包括 >、<、<=、>= 和 !=。 范围筛选器应在组合索引中最后定义。
考虑以下查询,其中包含一个相等性筛选器和两个范围筛选器:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age > 18 AND
c._ts > 1612212188
如果针对 (name ASC, age ASC) 和 (name ASC, _ts ASC) 使用组合索引,此查询会更高效。 但是,该查询不会针对 (age ASC, name ASC) 利用组合索引,因为相等性筛选器的属性必须在组合索引中首先定义。 需要两个单独的组合索引,而不是针对 (name ASC, age ASC, _ts ASC) 的单个组合索引,因为每个组合索引只能优化一个范围筛选器。
为具有多个属性的筛选器的查询创建复合索引时,将考虑以下事项:
筛选表达式可以使用多个复合索引。
查询筛选器中的属性应与复合索引中的属性匹配。 如果属性位于复合索引中,但不作为筛选器包含在查询中,则查询不使用复合索引。
当查询筛选复合索引中不包含的属性时,复合索引和范围索引的组合用于评估查询。 与仅依赖范围索引相比,此方法消耗的 RU 更少。
如果某个属性包含范围筛选器(
>、<、<=、>=或!=),则此属性应在组合索引中最后定义。 如果查询有多个范围筛选器,则可能会受益于多个组合索引。创建复合索引以使用多个筛选器优化查询时,
ORDER复合索引对结果没有影响。 此属性是可选的。
考虑以下示例,其中针对属性 name、age 和 timestamp 定义了组合索引:
| 复合索引 | 示例查询 | 受复合索引支持吗? |
|---|---|---|
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT COUNT(1) FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name DESC, age ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age > 18 |
Yes |
(name ASC, age ASC) |
SELECT * FROM c WHERE c.name != "John" AND c.age > 18 |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age = 18 AND c.timestamp > 123049923 |
Yes |
(name ASC, age ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp = 123049923 |
No |
(name ASC, age ASC) and (name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.age < 18 AND c.timestamp > 123049923 |
Yes |
使用筛选器和 ORDER BY 的查询
如果查询针对一个或多个属性进行筛选,并在 ORDER BY 子句中包含不同的属性,则将筛选器中的属性添加到 ORDER BY 子句可能会有帮助。
例如,通过将筛选器中的属性添加到 ORDER BY 子句,可以重写以下查询来应用组合索引:
使用范围索引的查询:
SELECT
*
FROM
container c
WHERE
c.name = "John"
ORDER BY
c.timestamp
使用组合索引的查询:
SELECT
*
FROM
container c
WHERE
c.name = "John"
ORDER BY
c.name,
c.timestamp
相同的查询优化可以针对带有筛选器的任何 ORDER BY 查询进行通用化,请记住,单个组合索引最多只能支持一个范围筛选器。
使用范围索引的查询:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age = 18 AND
c.timestamp > 1611947901
ORDER BY
c.timestamp
使用组合索引的查询:
SELECT
*
FROM
container c
WHERE
c.name = "John" AND
c.age = 18 AND
c.timestamp > 1611947901
ORDER BY
c.name,
c.age,
c.timestamp
此外,还可以使用复合索引来优化具有系统函数的查询,以及 ORDER BY:
使用范围索引的查询:
SELECT
*
FROM
container c
WHERE
c.firstName = "John" AND
CONTAINS(c.lastName, "Smith", true)
ORDER BY
c.lastName
使用组合索引的查询:
SELECT
*
FROM
container c
WHERE
c.firstName = "John" AND
CONTAINS(c.lastName, "Smith", true)
ORDER BY
c.firstName, c.lastName
创建组合索引以优化具有筛选器和 ORDER BY 子句的查询时,请注意以下事项:
如果在一个包含一个属性筛选器和一个使用不同属性的单独
ORDER BY子句的查询中未定义复合索引,该查询仍将成功。 但是,使用组合索引可以减少查询的 RU 开销,尤其是ORDER BY子句中的属性具有较高的基数时。如果查询针对属性进行筛选,应该首先将这些属性包含在
ORDER BY子句中。如果查询针对多个属性进行筛选,则相等性筛选器必须是
ORDER BY子句中的第一个属性。如果查询针对多个属性进行筛选,则每个组合索引最多可以使用一个范围筛选器或系统函数。 在范围筛选器或系统函数中使用的属性应在组合索引中最后定义。
有关为包含多个属性的
ORDER BY查询,以及为包含针对多个属性的筛选器的查询创建组合查询的所有注意事项仍然适用。
| 复合索引 | 示例 ORDER BY 查询 |
受复合索引支持吗? |
|---|---|---|
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" AND c.timestamp > 1589840355 ORDER BY c.name ASC, c.timestamp ASC |
Yes |
(timestamp ASC, name ASC) |
SELECT * FROM c WHERE c.timestamp > 1589840355 AND c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC, c.name ASC |
No |
(name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.name = "John" ORDER BY c.timestamp ASC |
No |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.age ASC, c.name ASC,c.timestamp ASC |
Yes |
(age ASC, name ASC, timestamp ASC) |
SELECT * FROM c WHERE c.age = 18 and c.name = "John" ORDER BY c.timestamp ASC |
No |
使用过滤条件和聚合功能的查询
如果查询针对一个或多个属性进行筛选并且具有聚合系统函数,则为筛选器和聚合系统函数中的属性创建组合索引可能会很有用。 此优化适用于 SUM 系统和 AVG 系统函数。
创建组合索引以优化具有筛选器和聚合系统函数的查询时,请注意以下事项。
在运行包含聚合的查询时,组合索引是可选的。 但是,使用组合索引通常可以降低查询的 RU 成本。
如果查询针对多个属性进行筛选,则相等性筛选器必须是组合索引中的第一个属性。
每个组合索引最多可以有一个范围筛选器,并且它必须针对聚合系统函数中的属性。
聚合系统函数中的属性应在组合索引中最后定义。
order(ASC或DESC)无关紧要。
| 复合索引 | 示例查询 | 受复合索引支持吗? |
|---|---|---|
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
Yes |
(timestamp ASC, name ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" |
No |
(name ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name > "John" |
No |
(name ASC, age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age = 25 |
Yes |
(age ASC, timestamp ASC) |
SELECT AVG(c.timestamp) FROM c WHERE c.name = "John" AND c.age > 25 |
No |
包含数组通配符的复合索引
下面是包含数组通配符的复合索引的示例:
{
"automatic": true,
"indexingMode": "Consistent",
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [],
"compositeIndexes": [
[
{
"path": "/familyname",
"order": "ascending"
},
{
"path": "/children/[]/age",
"order": "descending"
}
]
]
}
可受益于此复合索引的示例查询:
SELECT VALUE
p.id
FROM
products p
JOIN
t IN p.tags
WHERE
p.category = 'apparel' AND
p.order > 20
修改索引策略
对索引策略的更新会触发从旧索引到新索引的转换。 此转换是就地和在线同时执行的。 作期间不会占用额外的存储空间。 旧的索引策略会高效地向新策略转换,而不会影响写入可用性、读取可用性或针对容器预配的吞吐量。 索引转换是一个异步操作,完成该操作所需的时间取决于预配的吞吐量、项的数目及其大小。 如果需要进行多个索引策略更新,请在单个作中执行所有更改。 此方法允许索引转换更快地完成。
重要
索引转换是一种使用请求单位的操作。 可以使用其中一个 SDK 跟踪索引转换作的进度和消耗。
在任何索引转换期间,写入的可用性没有受到任何影响。 索引转换使用预配的 RU,但优先级低于 CRUD 操作或查询。
添加新索引路径时,读取可用性不会有影响。 查询仅在索引转换完成后使用新的索引路径。 换句话说,添加新索引路径时,利用该索引路径的查询在索引转换之前和期间的性能相同。 索引转换完成后,查询引擎将开始使用新的索引路径。
删除索引路径时,应将所有更改分组到一个索引策略转换中。 如果删除多个索引,并且是在一次索引策略更改中执行此操作,则查询引擎会在整个索引转换中提供一致且完整的结果。 但是,如果通过多个索引策略更改删除索引,则在所有索引转换完成之前,查询引擎不会提供一致或完整的结果。 大多数开发人员不会删除索引,然后立即尝试运行使用这些索引的查询。 在实践中,这种情况不太可能。
删除索引路径时,查询引擎会立即停止使用它并执行完全扫描。 如果可能,始终将多个索引删除分组到单个索引策略修改中。
移除索引的操作会立即生效,而添加新索引则需要一些时间,因为它需要进行索引转换。 请确保先添加新索引,然后在将一个索引替换为另一个索引时,先等待索引转换完成, 然后再 从索引策略中删除上一个索引。 例如,将单个属性索引替换为复合索引时,请遵循此策略。 否则,此错误会对查询上一个索引的能力产生负面影响,并可能会中断引用上一个索引的任何活动工作负荷。
索引策略和 TTL
使用 生存时间(TTL)功能 需要索引。
这一要求意味着:
无法在索引模式设置为
none的容器上激活 TTL,无法在激活 TTL 的容器上将索引模式设置为“无”。
对于不需要为任何属性路径编制索引,但需要 TTL 的情况,可以使用索引模式设置为 consistent、没有包含的路径并且将 /* 作为唯一排除的路径的索引策略。