原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/query-dsl-intervals-query.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/query-dsl-intervals-query.html

intervals 查询

根据匹配 词项(term) 的顺序和接近程度返回文档。

intervals 查询使用匹配规则(matching rules),这些规则由一小组定义构成。 然后将这些规则应用于指定 字段(field) 中的 词项(term)。

这些定义产生的最小区间序列跨越了文本主体中的词项(term)。 这些 间隔(interval) 可以由父源进一步组合和过滤。

请求示例

下面这个 intervals 搜索返回字段 my_text 中包含 my favorite food 的文档,且 my favorite food 后面紧跟着 hot water 或 cold porridge。

这个搜索会匹配字段 my_text 的值为 my favorite food is cold porridge 的文档,但不会匹配 when it's cold my favorite food is porridge。

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "ordered" : true,
          "intervals" : [
            {
              "match" : {
                "query" : "my favorite food",
                "max_gaps" : 0,
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "hot water" } },
                  { "match" : { "query" : "cold porridge" } }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

intervals的顶级参数

<field>

(必需的,规则(rule)对象) 你想搜索的字段。

该参数的值是一个规则(rule)对象,用于根据匹配的词项(term)、顺序(order)和接近性(proximity)来匹配文档。

可用的规则(rule)包括:

match(匹配) 规则参数

match 匹配规则匹配 已分析的文本(analyzed text)。

query
(必需的,string) 你想在指定的 <field> 中搜索的文本.
max_gaps

(可选, integer) 匹配词项之间的最大位置数。比这更远的词项不会被视为匹配。默认值为 -1。

如果未指定或设置为 -1,则匹配没有宽度限制。 如果设置为 0,这些词项必须相邻出现。

ordered
(可选,boolean) 如果为 true,匹配的词项必须按其指定的顺序出现。默认值为 false。
analyzer
(可选,string) 用于分析 query 中的 词项(term) 的 analyzer(分析器)。 默认为 <field> 的顶级 分析器(analyzer)。
filter
(可选,interval filter 规则对象) 一个可选的 interval filter。
use_field
(可选,string) 如果指定了,则匹配此 field 而不是顶级 <field> 的间隔。 使用 搜索分析器(search analyzer) 分析该字段中的词项(term)。 这将允许你跨多个字段进行搜索,就好像它们是同一个字段; 例如,你可以将相同的文本索引到 带词干(stemmed) 和 不带词干(unstemmed) 的字段,并在不带词干的字段附近搜索带词干的 词元(token)。

prefix(前缀) 规则参数

prefix(前缀) 规则匹配以指定字符集开头的词项。 这个前缀最多可以扩展到匹配 128 个词项。 如果前缀匹配超过 128 个词项,Elasticsearch 将返回一个错误。 可以在字段映射中使用 index-prefixes 选项来避免这个限制。

prefix
(必需的,string) 你希望在顶级 <field> 中查找的词项的开始字符。
analyzer
(可选,string) 用于归一化 prefix 的 analyzer(分析器)。 默认为 <field> 的顶级 分析器(analyzer)。
use_field

(可选,string) 如果指定了,则匹配此 field 而不是顶级 <field> 的间隔。

如果没有单独指定一个 analyzer,会使用字段的 搜索分析器(search analyzer) 对 prefix 进行归一化。

wildcard(通配符) 规则参数

wildcard 规则使用一个通配符模式匹配词项。 这个模式最多可以扩展到匹配 128 个词项。 如果前缀匹配超过 128 个词项,Elasticsearch 将返回一个错误。

pattern

(必需的,string) 用于查找匹配的词项的通配符模式。

该参数支持两个通配符操作符:

  • ?,它匹配任意的单个字符
  • *,它可以匹配零个或多个字符,包括一个空字符

避免模式以 * 或 ?开头。 这可能会增加查找匹配词项所需的迭代次数,并降低搜索性能。

analyzer
(可选,string) 用于归一化 pattern 的 analyzer(分析器)。 默认为 <field> 的顶级 分析器(analyzer)。
use_field

(可选,string) 如果指定了,则匹配此 field 而不是顶级 <field> 的间隔。

如果没有单独指定一个 analyzer,会使用字段的 搜索分析器(search analyzer) 对 pattern 进行归一化。

fuzzy(模糊) 规则参数

fuzzy 规则在由 fuzziness 定义的编辑距离内匹配与所提供的词项相似的词项。 如果模糊扩展匹配超过 128 项,Elasticsearch 将返回错误。
译者注: 请先了解 "编辑距离" (edit distance) 的有关概念。

term
(必需的,string) 要匹配的词项。
prefix_length
(可选,integer) 创建扩展时,开头字符保持不变的个数。默认为 0。
transpositions
(可选,boolean) 指示编辑是否包括两个相邻字符的换位(ab → ba)。默认为 true。
fuzziness
(可选,string) 匹配时允许的最大编辑距离。 默认值为 auto。 有关有效值和更多信息请参考 fuzziness。
analyzer
(可选,string) 用于对 term 进行归一化的 analyzer(分析器)。 默认为顶级 <field> 的分析器(analyzer)。
use_field

(可选,string) 如果指定了,则匹配此 field 而不是顶级 <field> 的间隔。

如果没有单独指定一个 analyzer,会使用字段的 搜索分析器(search analyzer) 对 term 进行归一化。

all_of(全部) 规则参数

all_of 规则返回跨越其他规则组合的匹配。

intervals
(必需的,规则对象数组) 要组合的规则数组。 所有规则都必须在文档中产生一个匹配项,以便整个源文件匹配。
max_gaps

(可选,integer) 匹配词项之间的最大位置数。由规则产生的间隔比这更远则不会被认为是匹配的。默认值为 -1。

如果未指定或设置为 -1,则匹配没有宽度限制。 如果设置为 0,这些词项必须相邻出现。

ordered
(可选,boolean) 如果为 true,匹配的词项必须按其指定的顺序出现。默认值为 false。
filter
(可选,interval filter 规则对象) 用于过滤返回的间隔的规则。

any_of(任意一个) 规则参数

any_of 规则返回由其任意一个子规则产生的间隔。

intervals
(必需的,规则对象的数组) 要匹配的规则的数组。
filter
(可选,interval filter 规则对象) 用于过滤返回的间隔的规则。

filter(过滤) 规则参数

filter 规则根据 查询(query) 返回间隔。 有关示例请参考 filter 示例。

after
(可选,query 对象) 用于返回 filter 规则中某个间隔之后的间隔的查询。 (原文: Query used to return intervals that follow an interval from the filter rule.)
before
(可选,query 对象) 用于返回 filter 规则中某个间隔之前发生的间隔的查询。
contained_by
(可选,query 对象) 用于从 filter 规则中返回间隔所包含的间隔的查询。
containing
(可选,query 对象) 用于返回包含 filter 规则中的间隔的间隔的查询。
not_contained_by
(可选,query 对象) 用于返回 filter 规则中的间隔不包含的间隔的查询。
not_containing
(可选,query 对象) 用于返回不包含 filter 规则中间隔的间隔的查询。
not_overlapping
(可选,query 对象) 用于返回与 filter 规则中的间隔不重叠的间隔的查询。
overlapping
(可选,query 对象) 用于返回与 filter 规则中的间隔重叠的间隔的查询。
script
(可选,脚本对象) 用于返回匹配文档的脚本。 这个脚本必须返回一个布尔值,true 或 false。 有关示例请参考 脚本过滤器(script filters)。

注意

filter 示例

下面这个例子包含一个 filter 规则。 它返回的文档中,单词 hot 和 porridge 的位置相差不超过 10 个,且中间没有单词 salty:

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "hot porridge",
          "max_gaps" : 10,
          "filter" : {
            "not_containing" : {
              "match" : {
                "query" : "salty"
              }
            }
          }
        }
      }
    }
  }
}

脚本过滤器 (script filters)

可以使用脚本根据间隔的开始(start)位置、结束(end)位置和内部间隙(gap)计数来过滤间隔。 下面这个 filter 脚本将 interval 变量与 start、end 和 gaps方法一起使用:

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "hot porridge",
          "filter" : {
            "script" : {
              "source" : "interval.start > 10 && interval.end < 20 && interval.gaps == 0"
            }
          }
        }
      }
    }
  }
}

最小限度(minimization)

intervals 查询总是最小化间隔,以确保查询可以线性时间运行。 这有时会导致令人惊讶的结果,尤其是在使用 max_gaps 限制或 filter 时。 例如,以下面的查询为例,搜索包含在短语 hot porridge 中的 salty:

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "salty",
          "filter" : {
            "contained_by" : {
              "match" : {
                "query" : "hot porridge"
              }
            }
          }
        }
      }
    }
  }
}

该查询与包含短语 hot porridge is salty porridge 的文档不匹配,因为 hot porridge 的匹配查询返回的间隔仅覆盖该文档中的前两个词项,并且这些词项与覆盖 salty 的间隔不重叠。

另一个需要注意的限制是包含重叠子规则的 any_of 规则的情况。 特别是,如果其中一个规则是另一个规则的严格 前缀(prefix),那么更长的规则永远不会匹配,这在与 max_gaps 结合使用时会导致意外。 考虑下面这个查询,搜索 the, 后面紧接着 big 或 big bad,然后后面再紧接着 wolf:

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "intervals" : [
            { "match" : { "query" : "the" } },
            { "any_of" : {
                "intervals" : [
                    { "match" : { "query" : "big" } },
                    { "match" : { "query" : "big bad" } }
                ] } },
            { "match" : { "query" : "wolf" } }
          ],
          "max_gaps" : 0,
          "ordered" : true
        }
      }
    }
  }
}

与直觉相反,这个查询与文档 the big bad wolf 不 匹配, 因为中间的 any_of 规则只产生 big的区间 - big bad 的区间比 big的区间长, 同时从相同的位置开始,因此被最小化。 在这些情况下,最好重写查询,以便所有选项都显式地显示在顶层:

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "any_of" : {
          "intervals" : [
            { "match" : {
                "query" : "the big bad wolf",
                "ordered" : true,
                "max_gaps" : 0 } },
            { "match" : {
                "query" : "the big wolf",
                "ordered" : true,
                "max_gaps" : 0 } }
           ]
        }
      }
    }
  }
}