间隔查询
间隔查询根据匹配术语的接近度和顺序匹配文档。它将一组匹配规则应用于指定字段中包含的术语。该查询生成跨越文本中术语的最小间隔序列。您可以组合这些间隔并通过父源进行过滤。
考虑包含以下文档的索引
PUT testindex/_doc/1
{
"title": "key-value pairs are efficiently stored in a hash table"
}
PUT /testindex/_doc/2
{
"title": "store key-value pairs in a hash map"
}
例如,以下查询搜索包含短语 key-value pairs
(术语之间没有间隔)后跟 hash table
或 hash map
的文档:
GET /testindex/_search
{
"query": {
"intervals": {
"title": {
"all_of": {
"ordered": true,
"intervals": [
{
"match": {
"query": "key-value pairs",
"max_gaps": 0,
"ordered": true
}
},
{
"any_of": {
"intervals": [
{
"match": {
"query": "hash table"
}
},
{
"match": {
"query": "hash map"
}
}
]
}
}
]
}
}
}
}
}
该查询返回这两个文档。
响应
{
"took": 1011,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.25,
"hits": [
{
"_index": "testindex",
"_id": "2",
"_score": 0.25,
"_source": {
"title": "store key-value pairs in a hash map"
}
},
{
"_index": "testindex",
"_id": "1",
"_score": 0.14285713,
"_source": {
"title": "key-value pairs are efficiently stored in a hash table"
}
}
]
}
}
参数
查询接受字段名称 (<field>
) 作为顶级参数
GET _search
{
"query": {
"intervals": {
"<field>": {
...
}
}
}
}
<field>
接受以下规则对象,这些对象用于根据术语、顺序和接近度匹配文档。
规则 | 描述 |
---|---|
匹配 (match) | 匹配分析过的文本。 |
prefix(前缀) | 匹配以指定字符集开头的术语。 |
通配符 (wildcard) | 使用通配符模式匹配术语。 |
模糊 (fuzzy) | 匹配在指定编辑距离内与提供术语相似的术语。 |
全部 (all_of) | 使用合取(AND )组合多个规则。 |
任意 (any_of) | 使用析取(OR )组合多个规则。 |
match
规则
match
规则匹配分析过的文本。下表列出了 match
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
查询 (query) | 必需 | 字符串 | 要搜索的文本。 |
分析器 | 可选 | 字符串 | 用于分析 query 文本的分析器。默认值是为 <field> 指定的分析器。 |
过滤器 (filter) | 可选 | 间隔过滤规则对象 | 用于过滤返回间隔的规则。 |
最大间隔 (max_gaps) | 可选 | 整数 | 匹配术语之间允许的最大位置数。超过 max_gaps 间隔的术语不被视为匹配。如果未指定 max_gaps 或将其设置为 -1 ,则无论位置如何,术语都被视为匹配。如果 max_gaps 设置为 0 ,则匹配术语必须彼此相邻出现。默认值为 -1 。 |
有序 (ordered) | 可选 | 布尔型 | 指定匹配术语是否必须按其指定顺序出现。默认值为 false 。 |
使用字段 (use_field) | 可选 | 字符串 | 指定搜索此字段而不是顶级字段 |
prefix
规则
prefix
规则匹配以指定字符集(前缀)开头的术语。前缀最多可以扩展匹配 128 个术语。如果前缀匹配的术语超过 128 个,则返回错误。下表列出了 prefix
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
prefix(前缀) | 必需 | 字符串 | 用于匹配术语的前缀。 |
分析器 | 可选 | 字符串 | 用于规范化 prefix 的分析器。默认值是为 <field> 指定的分析器。 |
使用字段 (use_field) | 可选 | 字符串 | 指定搜索此字段而不是顶级字段 |
wildcard
规则
wildcard
规则使用通配符模式匹配术语。通配符模式最多可以扩展匹配 128 个术语。如果模式匹配的术语超过 128 个,则返回错误。下表列出了 wildcard
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
模式 | 必需 | 字符串 | 用于匹配术语的通配符模式。指定 ? 匹配任意单个字符,或 * 匹配零个或多个字符。 |
分析器 | 可选 | 字符串 | 用于规范化 pattern 的分析器。默认值是为 <field> 指定的分析器。 |
使用字段 (use_field) | 可选 | 字符串 | 指定搜索此字段而不是顶级字段 |
以 *
或 ?
开头的模式可能会降低搜索性能,因为它增加了匹配术语所需的迭代次数。
fuzzy
规则
fuzzy
规则匹配在指定编辑距离内与提供术语相似的术语。模糊模式最多可以扩展匹配 128 个术语。如果模式匹配的术语超过 128 个,则返回错误。下表列出了 fuzzy
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
术语 (term) | 必需 | 字符串 | 要匹配的术语。 |
分析器 | 可选 | 字符串 | 用于规范化 term 的分析器。默认值是为 <field> 指定的分析器。 |
模糊度 (fuzziness) | 可选 | 字符串 | 在确定术语是否与值匹配时,将一个单词更改为另一个单词所需的字符编辑(插入、删除、替换)次数。例如,wined 和 wind 之间的距离为 1。有效值是非负整数或 AUTO 。默认值 AUTO 根据每个术语的长度选择一个值,并且适用于大多数用例。 |
换位 (transpositions) | 可选 | 布尔型 | 将 transpositions 设置为 true (默认值)会将相邻字符的交换添加到 fuzziness 选项的插入、删除和替换操作中。例如,如果 transpositions 为 true(交换“n”和“i”),则 wind 和 wnid 之间的距离为 1;如果为 false(删除“n”,插入“n”),则距离为 2。如果 transpositions 为 false ,则 rewind 和 wnid 与 wind 的距离相同(2),尽管以人为中心的观点认为 wnid 是一个明显的拼写错误。默认值适用于大多数用例。 |
前缀长度 (prefix_length) | 可选 | 整数 | 模糊匹配时保留不变的起始字符数。默认值为 0。 |
使用字段 (use_field) | 可选 | 字符串 | 指定搜索此字段而不是顶级字段 |
all_of
规则
all_of
规则使用合取(AND
)组合多个规则。下表列出了 all_of
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
间隔 (intervals) | 必需 | 规则对象数组 | 要组合的规则数组。文档必须匹配所有规则才能在结果中返回。 |
过滤器 (filter) | 可选 | 间隔过滤规则对象 | 用于过滤返回间隔的规则。 |
最大间隔 (max_gaps) | 可选 | 整数 | 匹配术语之间允许的最大位置数。超过 max_gaps 间隔的术语不被视为匹配。如果未指定 max_gaps 或将其设置为 -1 ,则无论位置如何,术语都被视为匹配。如果 max_gaps 设置为 0 ,则匹配术语必须彼此相邻出现。默认值为 -1 。 |
有序 (ordered) | 可选 | 布尔型 | 如果为 true ,则规则生成的间隔应按指定顺序出现。默认值为 false 。 |
any_of
规则
any_of
规则使用析取(OR
)组合多个规则。下表列出了 any_of
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
间隔 (intervals) | 必需 | 规则对象数组 | 要组合的规则数组。文档必须至少匹配一个规则才能在结果中返回。 |
过滤器 (filter) | 可选 | 间隔过滤规则对象 | 用于过滤返回间隔的规则。 |
filter
规则
filter
规则用于限制结果。下表列出了 filter
规则支持的所有参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
之后 (after) | 可选 | 查询对象 | 用于返回在过滤器规则中指定间隔之后的间隔的查询。 |
之前 (before) | 可选 | 查询对象 | 用于返回在过滤器规则中指定间隔之前的间隔的查询。 |
包含于 (contained_by) | 可选 | 查询对象 | 用于返回被过滤器规则中指定间隔包含的间隔的查询。 |
包含 (containing) | 可选 | 查询对象 | 用于返回包含过滤器规则中指定间隔的间隔的查询。 |
不包含于 (not_contained_by) | 可选 | 查询对象 | 用于返回不被过滤器规则中指定间隔包含的间隔的查询。 |
不包含 (not_containing) | 可选 | 查询对象 | 用于返回不包含过滤器规则中指定间隔的间隔的查询。 |
不重叠 (not_overlapping) | 可选 | 查询对象 | 用于返回与过滤器规则中指定间隔不重叠的间隔的查询。 |
重叠 (overlapping) | 可选 | 查询对象 | 用于返回与过滤器规则中指定间隔重叠的间隔的查询。 |
script(脚本) | 可选 | 脚本对象 | 用于匹配文档的脚本。此脚本必须返回 true 或 false 。 |
示例:过滤器
以下查询搜索包含单词 pairs
和 hash
且彼此之间距离不超过五个位置,并且不包含单词 efficiently
的文档:
POST /testindex/_search
{
"query": {
"intervals" : {
"title" : {
"match" : {
"query" : "pairs hash",
"max_gaps" : 5,
"filter" : {
"not_containing" : {
"match" : {
"query" : "efficiently"
}
}
}
}
}
}
}
}
响应只包含文档 2
响应
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.25,
"hits": [
{
"_index": "testindex",
"_id": "2",
"_score": 0.25,
"_source": {
"title": "store key-value pairs in a hash map"
}
}
]
}
}
示例:脚本过滤器
或者,您可以使用以下变量编写自己的脚本过滤器,以包含在 intervals
查询中:
interval.start
:间隔开始的位置(术语编号)。interval.end
:间隔结束的位置(术语编号)。interval.gap
:术语之间的单词数。
例如,以下查询搜索在指定间隔内彼此相邻的单词 map
和 hash
。术语从 0 开始编号,因此在文本 store key-value pairs in a hash map
中,store
位于位置 0,key
位于位置 1
,依此类推。指定的间隔应在 a
之后开始,在字符串末尾之前结束:
POST /testindex/_search
{
"query": {
"intervals" : {
"title" : {
"match" : {
"query" : "map hash",
"filter" : {
"script" : {
"source" : "interval.start > 5 && interval.end < 8 && interval.gaps == 0"
}
}
}
}
}
}
}
响应包含文档 2
响应
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.5,
"hits": [
{
"_index": "testindex",
"_id": "2",
"_score": 0.5,
"_source": {
"title": "store key-value pairs in a hash map"
}
}
]
}
}
间隔最小化
为确保查询以线性时间运行,intervals
查询会最小化间隔。例如,考虑一个包含文本 a b c d c
的文档。您可以使用以下查询搜索包含在 a
和 c
之间的 d
:
POST /testindex/_search
{
"query": {
"intervals" : {
"my_text" : {
"match" : {
"query" : "d",
"filter" : {
"contained_by" : {
"match" : {
"query" : "a c"
}
}
}
}
}
}
}
}
该查询不返回任何结果,因为它匹配前两个术语 a c
并且在此术语之间找不到 d
。