原英文版地址: 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 watercold 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) 用于归一化 prefixanalyzer(分析器)。 默认为 <field> 的顶级 分析器(analyzer)。
use_field

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

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

wildcard(通配符) 规则参数

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

pattern

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

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

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

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

analyzer
(可选,string) 用于归一化 patternanalyzer(分析器)。 默认为 <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
(可选,脚本对象) 用于返回匹配文档的脚本。 这个脚本必须返回一个布尔值,truefalse。 有关示例请参考 脚本过滤器(script filters)

注意

filter 示例

下面这个例子包含一个 filter 规则。 它返回的文档中,单词 hotporridge 的位置相差不超过 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 变量与 startendgaps方法一起使用:

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, 后面紧接着 bigbig 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 } }
           ]
        }
      }
    }
  }
}