【问题标题】:Indexing arrays in CosmosDBCosmosDB 中的索引数组
【发布时间】:2018-05-31 00:07:16
【问题描述】:

为什么 CosmosDB 默认不索引数组?默认索引路径为

"path": "/*"

这不是意味着“索引所有内容”吗?不是“索引除数组之外的所有内容”。

如果我将数组字段添加到索引中,如下所示:

"path": "/tags/[]/?"

它将工作并开始索引该特定数组字段。

但我的问题是为什么“索引所有内容”不索引所有内容?

编辑:这是一篇描述我所看到的行为的博客文章。 http://www.devwithadam.com/2017/08/querying-for-items-in-array-in-cosmosdb.html Array_Contains 查询很慢,显然没有使用索引。如果您将相关字段显式添加到索引中,则查询速度很快(显然它们开始使用索引)。

【问题讨论】:

  • 默认情况下所有属性都被索引,包括数组属性。好奇你为什么建议他们不是。您有遇到问题的特定查询吗?如果是这样,请编辑您的问题以澄清您的具体问题。正如所写,这个问题不清楚,因为我们不知道您的具体问题。
  • @DavidMakogon 数组默认情况下不被索引(尽管我同意它们应该被索引,并且所有文档都表明它们是,但它们不是。)如果没有对内容的显式数组索引查询阵列需要 10 秒并花费数千个 RU。添加该索引,查询会立即返回并花费几个 RU。这里有一篇关于它的博客文章:devwithadam.com/2017/08/…
  • 您能否说明您使用的是哪个 API?
  • 我使用 Microsoft.Azure.DocumentDB.Core 包。而且我还使用 Cerebrata Cerulean 工具。
  • 这不再是新配置的集合的问题

标签: azure azure-cosmosdb


【解决方案1】:

“新”索引布局

Index Types中所述

Azure Cosmos 容器支持不再使用的新索引布局 哈希索引类型。如果您在索引上指定哈希索引类型 策略,容器上的 CRUD 请求将默默地忽略 索引种类和来自容器的响应仅包含范围 索引种类。所有新的 Cosmos 容器都使用新的索引布局 默认。

以下问题适用于新的索引布局。默认索引策略在那里工作正常(并在36.55 RUs 中提供结果)。但是,已有的集合可能仍在使用旧的布局。

“旧”索引布局

我能够通过ARRAY_CONTAINS 重现您所询问的问题。

使用来自 SO 数据转储的 100,000 个帖子设置 CosmosDB 集合(例如,此问题将表示如下)

{
    "id": "50614926",
    "title": "Indexing arrays in CosmosDB",
     /*Other irrelevant properties omitted */
    "tags": [
        "azure",
        "azure-cosmosdb"
    ]
}

然后执行以下查询

SELECT COUNT(1)
FROM t IN c.tags
WHERE t = 'sql-server'

该查询使用默认索引策略占用了 2,000 个 RU,并通过以下添加获取了 93 个(如您链接的文章中所示)

{
    "path": "/tags/[]/?",
    "indexes": [
        {
            "kind": "Hash",
            "dataType": "String",
            "precision": -1
        }
    ]
}

但是您在这里看到的是不是默认情况下数组值没有被索引。只是默认范围索引对您的查询没有用处。

范围索引使用基于部分正向路径的键。所以会包含如下路径。

  • tags/0/azure
  • tags/0/c#
  • tags/0/oracle
  • tags/0/sql-server
  • tags/1/azure-cosmosdb
  • tags/1/c#
  • tags/1/sql-server

使用此索引结构,它从tags/0/sql-server 开始,然后读取所有剩余的tags/0/ 条目和tags/n/ 的全部条目,其中n 是一个大于0 的整数。需要检索和评估映射到其中任何一个的每个不同的文档。

相比之下,哈希索引使用反向路径 (more details - PDF)

StackOverflow 理论上允许 UI 最多为每个问题添加 5 个标签,因此在这种情况下(忽略一些问题通过站点管理活动具有更多标签的事实)感兴趣的反向路径是

  • sql-server/0/tags
  • sql-server/1/tags
  • sql-server/2/tags
  • sql-server/3/tags
  • sql-server/4/tags

使用反向路径结构查找所有叶节点值为 sql-server 的路径是直截了当的。

在这个特定用例中,由于数组被限制为最多 5 个可能的值,因此也可以通过仅查看这些特定路径来有效地使用原始范围索引。

以下查询在我的测试集合中使用了默认索引策略的 97 个 RU。

SELECT COUNT(1)
FROM c
WHERE  'sql-server' IN (c.tags[0], c.tags[1], c.tags[2], c.tags[3], c.tags[4])

【讨论】:

    【解决方案2】:

    Cosmos DB 会索引 Array 的所有元素。默认情况下,所有 Azure Cosmos DB 数据都已编入索引。在此处阅读更多信息https://docs.microsoft.com/en-us/azure/cosmos-db/indexing-policies

    【讨论】:

    • 它没有。如果没有对数组内容的显式数组索引查询,则需要 10 秒并花费数千个 RU。添加该索引,查询会立即返回并花费几个 RU。这里有一篇关于它的博客文章:devwithadam.com/2017/08/…
    • 我再次阅读了该文档(我已经阅读了很多次),它实际上并没有说所有数据都已编入索引。它表示所有文档都已编入索引。不是一回事。所以我的问题是成立的。为什么 "path": "/*" 不应该索引所有数据。
    猜你喜欢
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多