即使手动指定,芒果索引“不包含此查询的有效索引”

问题描述

我正在尝试通过 Mango 有效地查询数据(鉴于我的要求 Searching for sub-objects with a date range containing the queried date value,这似乎是唯一的选择),但我什至无法获得一个非常简单的索引/查询对:虽然我为查询手动指定了我的索引,我被告知我的索引“未被使用,因为它不包含此查询的有效索引。找不到匹配的索引,创建一个索引以优化查询时间。”

(我在 CouchDB v. 3.0.0 上通过 Fauxton 完成所有这些)

假设我的文档如下所示:

{
    "tenant": "TNNT_a","$doctype": "Jobopening",// a bunch of other fields
}

所有 $doctype 为“Jobopening”的文档都保证具有 tenant 属性。我希望执行的搜索将永远只针对具有“Jobopening”的 $doctype 的文档,并且在查询时将始终提供 tenant 选择器。

这是我配置的测试索引:

{
   "index": {
      "fields": [
          "tenant","$doctype"
      ],"partial_filter_selector": {
        "\\$doctype": {
          "$eq": "Jobopening"
        }
      }
   },"ddoc": "job-openings-doctype-index","type": "json"
}

这是查询

{
   "selector": {
      "tenant": "TNNT_a","\\$doctype": "Jobopening"
   },"use_index": "job-openings-doctype-index"
}

为什么不使用索引进行查询

我尝试不使用部分索引,我认为 $doctype 转义在必要的地方正确完成,但似乎没有什么可以阻止 CouchDB 执行完整扫描。

解决方法

未使用索引,因为查询规划器未按预期识别 $doctype 字段。

将设计文档中的字段声明从 $doctype 更改为 \\$doctype 解决了该问题。

{
   "index": {
      "fields": [
          "tenant","\\$doctype"
      ],"partial_filter_selector": {
        "\\$doctype": {
          "$eq": "JobOpening"
        }
      }
   },"ddoc": "job-openings-doctype-index","type": "json"
}

在那个小的重构之后,查询

    {
       "selector": {
          "tenant": "TNNT_a","\\$doctype": "JobOpening"
       },"use_index": "job-openings-doctype-index"
    }

返回预期的结果,并产生一个“解释”,确认 job-openings-doctype-index 被查询:

{
 "dbname": "stack","index": {
  "ddoc": "_design/job-openings-doctype-index","name": "7f5c5cea5acd90f11fffca3e3355b6a03677ad53","type": "json","def": {
   "fields": [
    {
     "tenant": "asc"
    },{
     "\\$doctype": "asc"
    }
   ],"partial_filter_selector": {
    "\\$doctype": {
     "$eq": "JobOpening"
    }
   }
  }
 },// etc etc etc

这种变化是否直观尚不清楚,但它是一致的 - 并且可能不希望显示带有“特殊”字符的前导字段名称。

关于过滤字段的索引,按照 documentation regarding partial_filter_selector

从技术上讲,我们不需要在“状态”中包含过滤器 [例如 $doctype here] 查询选择器中的字段 - 部分索引 确保这总是正确的 - 但包括它使意图 选择器更清晰,更容易利用未来 查询计划的改进(例如自动选择部分 索引)。

尽管如此,我不会选择索引值为常量的字段。