查询DSL(Query DSL)
本文为翻译官网“Query DSL”部分但有一定改动之后的文章
官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html
Elasticsearch提供了基于JSON的完整的查询DSL(Domain Specific Language-领域特定语言)来定义查询。可以把查询DSL看作查询的AST(Abstract Syntax Tree-抽象语法树),由两种类型的子句组成:
Leaf query clauses(叶查询字句)
叶查询子句在特定字段中查找特定值,如match
、term
或range
。这些查询可以被他们自己使用。
Compound query clauses(复合查询字句)
复合查询子句包装了其他叶查询或复合查询,并用于以逻辑方式组合多个查询(如bool或dis_max查询),或更改它们的行为(如constant_score查询)。
查询子句的行为取决于它们是在查询上下文中使用还是在过滤上下文中使用。
查询和过滤上下文
Relevance scores(相关性分数)
默认情况下,Elasticsearch根据相关性评分对匹配的搜索结果进行排序,相关性评分衡量每个文档与查询的匹配程度。
相关性评分是一个正浮点数,在搜索API的_score元字段中返回。_score越高,说明文档越相关。虽然每种查询类型可以以不同的方式计算相关性得分,但得分计算也取决于查询子句是在查询(query)上下文中运行还是在过滤器(filter)上下文中运行。
Query context(查询上下文)
在查询上下文中,查询子句回答“此文档与此查询子句匹配程度如何?”除了决定文档是否匹配之外,查询子句还在_score元字段中计算一个相关性得分。
PS:即在搜索的同时会计算此次搜索所有的文档得分
只要将查询子句传递给查询参数(例如搜索API中的查询参数),查询上下文就会生效。
Filter context(过滤上下文)
在过滤器上下文中,查询子句回答“此文档是否与此查询子句匹配?”答案是简单的“是”或“否”——分数是计算出来的。过滤上下文主要用于过滤结构化数据,例如:
- 这个时间戳是否在2015年到2016年之间?
- 状态字段是否设置为“已发布”?
PS:搜索中不会计算分数
经常使用的过滤器将被Elasticsearch自动缓存,以加快性能。
每当查询子句传递给过滤器参数时,过滤器上下文就会生效,例如bool查询中的Filter
或must_not
参数、constant_score
查询中的filter
参数或filter
聚合。
查询和筛选上下文的示例
下面是在搜索API的查询和过滤上下文中使用查询子句的示例。该查询将匹配满足以下所有条件的文档:
title
字段包含单词search
content
字段包含elasticsearch
status
字段包含完整的published
publish_date
字段包含从2015年1月1日起的日期
GET /_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
- query参数表示查询上下文。
- bool和两个match子句用于查询上下文中,这意味着它们用于对每个文档的匹配程度进行评分。
- filter参数指示过滤器上下文。它的term和range子句用于过滤器上下文中。它们会过滤掉不匹配的文档,但不会影响匹配文档的得分。
在查询上下文中为查询计算的分数表示为单精度浮点数;他们只有24位的有效精度。超过显著值精度的分数计算将被转换为精度损失的浮点数。
在查询上下文中使用查询子句来处理应该影响匹配文档得分的条件(即文档匹配的程度),并在过滤器上下文中使用所有其他查询子句。
复合查询(Compound queries)
复合查询包装其他复合查询或叶查询,可以组合它们的结果和分数,更改它们的行为,或者从查询切换到过滤上下文。
复合查询有:
bool query(布尔查询):
用于组合多个叶查询子句或复合查询子句的默认查询,如must、should、must_not或filter子句。must和should子句在查询上下文中,而must_not和filter子句在filter上下文中执行。
**boosting query: **
返回与positive查询匹配的文档,但降低negative查询匹配的文档的得分。
constant_score query:
封装另一个查询,但在过滤器上下文中执行它的查询。所有匹配文档都被赋予相同的“常量”_score
。
dis_max query:
接受多个查询并返回与查询子句匹配的任何文档的查询。bool查询结合了所有匹配查询的得分,而dis_max查询使用单个最佳匹配查询子句的得分。
function_score query:
使用函数修改主查询返回的分数,例如:流行度、最近度、距离或使用script(脚本)
实现的自定义算法等因素。
Bool Query(布尔查询)
匹配与其他查询的布尔组合匹配的文档的查询。bool查询映射到Lucene BooleanQuery。它是使用一个或多个布尔子句构建的,每个子句都有一个类型发生。发生类型为:
must
: 子句(查询)必须出现在匹配的文档中,并将有助于评分。filter
: 子句(查询)必须出现在匹配的文档中。然而,与must不同的是,查询的分数将被忽略。filter子句在过滤器上下文中执行,这意味着评分被忽略,子句被考虑用于缓存(即在内存中缓存查询结果)。should
: 子句(查询)应该出现在匹配的文档中。must_not
: 子句(查询)不能出现在匹配的文档中。子句在过滤器上下文中执行,这意味着评分将被忽略,子句将被考虑用于缓存。因为评分被忽略,所以所有文档的评分都为0。
bool查询采用了“更多匹配即更好”的方法,因此每个匹配的must或should子句的得分将被加在一起,以提供每个文档的最终_score。
POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user" : "kimchy" }
},
"filter": {
"term" : { "tag" : "tech" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tag" : "wow" } },
{ "term" : { "tag" : "elasticsearch" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}
minimum_should_match
:该参数后面章节会介绍
boost
: 提升查询权重
使用Bool.filter查询评分
在filter
下指定的查询对评分没有影响——评分返回为0。分数只受指定的查询的影响。例如,以下三个查询都返回status字段值为active
的所有文档。
GET _search
{
"query": {
"bool": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
这个bool查询有一个match_all查询,它为所有文档分配1.0分。
GET _search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"status": "active"
}
}
}
}
}
constant_score
查询的行为与上面第二个例子完全相同。constant_score
查询为filter
查询的所有文档分配1.0分。
GET _search
{
"query": {
"constant_score": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
使用命名查询查看哪些子句匹配
如果需要知道bool查询中的哪个子句与查询返回的文档匹配,可以使用命名查询为每个子句分配名称。
例如:
Boosting query(改分查询)
返回与
positive
查询匹配的文档,同时降低nagative
查询匹配的文档的相关性得分。
您可以使用boosting query
(提升查询)来降低某些文档的级别,而不会将它们从搜索结果中排除。
例如:
GET /_search
{
"query": {
"boosting" : {
"positive" : {
"term" : {
"text" : "apple"
}
},
"negative" : {
"term" : {
"text" : "pie tart fruit crumble tree"
}
},
"negative_boost" : 0.5
}
}
}
boosting query的顶级参数:
-
positive
: (必选,查询对象)要运行的查询。任何返回的文档都必须与此查询匹配。 -
nagative
:(必选,查询对象)用于降低匹配文档的相关性得分。如果返回的文档同时匹配
positive
查询和此查询,提升查询计算文档的最终相关性得分如下:- 从
positive
查询中获取原始的相关性得分。 - 将分数乘以
negative_boost
值。
- 从
-
negative_boost
: (必选,float) 0到1.0之间的浮点数,用于降低与否定查询匹配的文档的相关性得分。
Constant score query(恒分查询)
包装
filter
查询并返回与boost参数值相等的相关性评分的每个匹配文档。
GET /_search
{
"query": {
"constant_score" : {
"filter" : {
"term" : { "user" : "kimchy"}
},
"boost" : 1.2
}
}
}
constant score查询的核心参数:
-
filter
: (必选,查询对象)筛选您希望运行的查询。任何返回的文档都必须与此查询匹配。过滤器查询不计算相关性分数。为了提高性能,Elasticsearch会自动缓存经常使用的过滤器查询。
-
boost
: (可选,float)用于每个匹配过滤器查询的文档的恒定相关性评分的浮点数。默认为1.0。上面的例子即将每个文档的返回的评分改为1.2
Disjunction max query(dis_max)(分离最大化查询)
返回匹配一个或多个包装查询(称为查询子句或子句)的文档。
如果返回的文档匹配多个查询子句,dis_max查询将从任何匹配子句中为文档分配最高的相关性得分,并为任何额外的匹配子查询加上破一行增量。
可以使用dis_max搜索拥有不同搜索术语的映射。
分离(Disjunction)的意思是 或(or) ,这与可以把结合(conjunction)理解成 与(and) 相对应。分离最大化查询(Disjunction Max Query)指的是: 将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回 :
GET /_search
{
"query": {
"dis_max" : {
"queries" : [
{ "term" : { "title" : "Quick pets" }},
{ "term" : { "body" : "Quick pets" }}
],
"tie_breaker" : 0.7
}
}
}
核心参数:
queries
: (必选,查询对象数组)包含一个或多个查询子句。返回的文档必须匹配其中一个或多个查询。如果一个文档匹配多个查询,Elasticsearch使用最高的相关性评分。
tie_breaker
: (可选,float) 0到1.0之间的浮点数,用于增加匹配多个查询子句的文档的相关性得分。默认为0.0。
您可以使用tie_breaker值为在多个字段中包含相同术语的文档分配更高的相关性得分,而不是只在这些字段中最好的情况下包含该术语的文档,而不会将其与在多个字段中包含两个不同术语的较好情况混淆。
如果一个文档匹配多个子句,dis_max查询计算文档的相关性得分如下:
- 从得分最高的匹配子句中获取相关性得分。
- 将来自任何其他匹配子句的分数乘以tie_breaker值。
- 把最高分加到相乘的分数中。
如果tie_breaker值大于0.0,则所有匹配子句都计数,但得分最高的子句计数最多。
Function score query
function_score
允许您修改查询检索到的文档的分数。例如,如果评分函数的计算成本很高,并且它足以计算经过筛选的一组文档的评分,那么这将非常有用。要使用function_score,用户必须定义一个查询以及一个或多个函数,为查询返回的每个文档计算新分数。
例如:
GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"random_score": {},
"boost_mode":"multiply"
}
}
}
其中的random_score
则代表查询使用的函数
此外,还可以组合多个函数。在这种情况下,可以选择仅在匹配的时候使用filter
查询时应用该函数:
GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"functions": [
{
"filter": { "match": { "test": "bar" } },
"random_score": {},
"weight": 23
},
{
"filter": { "match": { "test": "cat" } },
"weight": 42
}
],
"max_boost": 42,
"score_mode": "max",
"boost_mode": "multiply",
"min_score" : 42
}
}
}
如果functions
中得查询没有指定filter
参数,那么默认是match_all
查询
首先,根据定义的函数对每个文档进行评分。参数score_mode
指定计算分数的组合方式:
multiply
: 默认方式,将多个函数的分数相乘sum
: 分数相加avg
: 取分数的平均值first
: 应用第一个具有filter
查询的函数max
: 取分数的最大值min
: 取分数的最小值
因为分数可以在不同的尺度上(例如,衰减函数在0到1之间,而field_value_factor是任意的),也因为有时函数对分数的不同影响是可取的,每个函数的分数可以通过用户定义的权重进行调整。权重可以在函数数组(例如上面的例子)中为每个函数定义,并与各自函数计算的分数相乘。如果给出了weight而没有任何其他函数声明,则weight作为一个函数仅返回权重。
在score_mode设置为平均的情况下,各个分数将由加权平均组合。例如,如果两个函数返回分数1和2,并且它们各自的权重为3和4,那么它们的分数将合并为(13+24)/(3+4),而不是(13+24)/2。
通过设置max_boost参数,可以将新分数限制为不超过某个限制。max_boost的默认值是FLT_MAX。
函数计算的分数与查询的分数相结合。参数boost_mode
定义了如何:
multiply
: 查询分数与函数分数相乘,默认方式replace
: 只使用函数分数,忽略查询分数sum
: 函数分数与查询分数相加avg
: 平均值max
: 函数分数与查询分数的最大值min
: 函数分数与查询分数的最小值
默认情况下,修改分数不会改变匹配的文档。为了排除不满足某个评分阈值的文档,可以将min_score
参数设置为所需的评分阈值。为了让min_score工作,需要对查询返回的所有文档进行评分,然后逐一过滤掉。
function_score
查询支持一下几种函数:
script_score
weight
random_score
field_value_factor
decay functions(衰减函数)
:guass,linear,exp
Script_score(脚本评分)
script_score函数允许您包装另一个查询,并使用脚本表达式使用从文档中的其他数值字段值派生的计算可选地自定义它的评分。下面是一个简单的例子:
GET /_search
{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"script_score" : {
"script" : {
"source": "Math.log(2 + doc['likes'].value)"
}
}
}
}
}
script_score函数生成的分数必须是非负的,否则将抛出异常。
在不同的脚本字段值和表达式之上,可以使用_score脚本参数基于包装的查询检索分数。
缓存脚本编译以加快执行速度。如果脚本有它需要考虑的参数,最好重用相同的脚本,并为它提供参数:
GET /_search
{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"script_score" : {
"script" : {
"params": {
"a": 5,
"b": 1.2
},
"source": "params.a / Math.pow(params.b, doc['likes'].value)"
}
}
}
}
}
注意,与custom_score查询不同的是,查询的分数与脚本评分的结果相乘。如果你不想使用这种方式,设置"boost_mode": “replace”
weight(权重)
weight
允许您将该分数乘以所提供的权重。有时候我们需要这样做,因为在特定查询上设置的boost值得到了规范化,但是评分函数不一样。下面number值的类型为float。
"weight":number
Random(随机)
random_score生成从0到但不包括1的均匀分布的分数。默认情况下,它使用Lucene内部的文档id作为随机性的来源,这是非常有效的,但不幸的是不能复制,因为文档可能会通过合并重新编号。
如果你想要分数是可复制的,可以提供种子和场地。最后的分数将根据这个种子、考虑文档的字段的最小值和一个基于索引名和分片id计算的加盐计算,这样具有相同值但存储在不同索引中的文档将获得不同的分数。请注意,位于同一个分片内且具有相同字段值的文档将获得相同的分数,因此通常需要使用对所有文档具有惟一值的字段。一个好的默认选择可能是_seq_no
字段
不设置字段也可以设置种子,但这已经被弃用了,因为这需要在_id字段上加载fielddata,这会消耗大量内存。
GET /_search
{
"query": {
"function_score": {
"random_score": {
"seed": 10,
"field": "_seq_no"
}
}
}
}
Field Value factor
field_value_factor函数允许使用文档中的字段来影响评分。它类似于使用script_score函数,但是,它避免了脚本编写的开销。如果用于多值字段,则只使用该字段的第一个值进行计算。
举个例子,假设你有一个用数字likes字段索引的文档,并且希望用这个字段影响文档的得分,这样做的示例如下:
GET /_search
{
"query": {
"function_score": {
"field_value_factor": {
"field": "likes",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
}
}
这将转化为以下的评分公式:
sqrt(1.2 * doc['likes'].value)
field_value_factor函数有很多选项:
field
: 要从文档中提取的字段。factor
: 可选因子乘以字段值,默认为1。modifier
: 修饰符应用于字段值,可以是none、log、log1p、log2p、ln、ln1p、ln2p、square、sqrt或reciprocal之一。默认为none。
modifier修饰符含义:
none
: 没有对字段值应用任何乘数log
: 取字段值的公对数。由于此函数将返回一个负值,如果使用在0到1之间的值,则会导致错误,因此建议使用log1p代替。log1p
:字段值加1,取公对数log2p
:字段值加2,取公对数ln
: 取字段值的自然对数。由于此函数将返回一个负值,如果使用在0到1之间的值,则会导致错误,因此建议使用ln1p代替。ln1p
: 字段值加1,取自然对数ln2p
: 字段值加2,取自然对数square
: 字段值的平方(乘以它自己)sqrt
: 取字段值的平方根reciprocal
: 取字段值的倒数,与1/x相同,其中x是字段的值
Decay functions(衰减函数)
暂不翻译解释,如需要可评论,博主看情况翻译
全文搜索(Full text queries)
全文查询使您能够搜索已分词的文本字段,例如电子邮件的正文。使用索引期间应用于字段的相同分析程序处理查询字符串。
查询包括:
-
intervals query(区间查询)
一种全文查询,允许对匹配项的顺序和接近性进行细粒度控制。
-
match query
执行全文查询的标准查询,包括模糊匹配和短语查询或相似查询。
-
match_bool_prefix query
创建一个bool查询,将每个术语作为术语查询进行匹配,但最后一个术语作为前缀查询进行匹配
-
match_phrase query
类似于匹配查询,但用于匹配精确短语或单词相似匹配。
-
match_phrase_prefix query
类似于match_phrase查询,但对最终的单词进行通配符搜索。
-
multi_match query
匹配查询的多字段版本。
-
common terms query
一个更专业的查询,它给不常见的单词更多的优先级。
-
query_string query
支持紧凑的Lucene查询字符串语法,允许您在单个查询字符串中指定AND|OR|NOT条件和多字段搜索。仅供专业用户使用。
-
simple_query_string query
query_string语法的一个更简单、更健壮的版本,适合直接向用户公开。
Intervals(区间查询)
根据匹配项的顺序和相似度返回文档。
intervals
查询使用匹配规则,按照小组构建,这些规则来自特殊的字段
定义产生最小间隔序列,这些序列跨越文本主体中的术语。这些间隔可以由父源进一步组合和过滤。
下面的intervals
搜索在my_text字段中返回包含"我最喜欢的食物"的文档,将区间限制在"热水"或"冷粥"。
下面这个搜索应该匹配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
:(必选,规则对象)要搜索的字段。如上述例子的my_text
字段
此参数的值是一个规则对象,用于根据匹配术语、顺序和接近性来匹配文档。
规则对象包含:
match
prefix
wildcard
all_of
any_of
filter
match
参数规则:
match匹配分词的文本
-
query
(Required, string)您希望在提供的中找到的文本。
-
max_gaps
(可选,整数)匹配项之间的最大位置数。超过这个距离的术语不被认为是匹配的。默认值为-1。
如果未指定或设置为-1,则匹配没有宽度限制。如果设置为0,则这些项必须出现在彼此旁边。
-
ordered
(可选,boolean)如果为true,匹配的项必须以指定的顺序出现。默认为false。
-
analyzer
(可选,字符串)分词器用于分析查询中的术语。默认为顶级的的分析器。
-
filter
(可选,interval过滤规则对象)可选的间隔过滤器。
-
use_field
(可选,字符串)如果指定,则匹配该字段的间隔,而不是顶级的。使用该领域的搜索分词器对术语进行分析。这允许你搜索多个字段,就好像它们都是相同的字段一样;例如,您可以将相同的文本索引到有词根字段和无词根字段中,并在无词根字段附近搜索有词根标记。
prefix
参数规则:
前缀规则匹配以指定字符集开头的术语。该前缀最多可以扩展到匹配128个项。如果前缀匹配超过128个词,Elasticsearch将返回一个错误。您可以在字段映射中使用index-prefixes选项来避免此限制。
-
prefix
(必选,字符串)您希望在顶级中找到的术语的开头字符。
-
analyzer
(可选,字符串)分词器用于规范化前缀。默认为顶级的的分析器。
-
use_field
(可选,字符串)如果指定,则匹配该字段的间隔,而不是顶级的。
除非指定了单独的分词器,否则使用该字段的搜索分词器对前缀进行规范化。
wildcard
参数规则:
通配符规则匹配使用通配符模式的术语。该模式最多可以扩展到匹配128个术语。如果模式匹配超过128个术语,Elasticsearch将返回一个错误。
-
pattern
(必选,字符串)通配符模式用于查找匹配的术语。
该参数支持两个通配符:
1,
?
:匹配任何单个字符2,
*
:可以匹配零个或多个字符,包括一个空字符避免使用*或?开头模式。这可能会增加查找匹配项所需的迭代次数,并降低搜索性能。
-
analyzer
(可选,字符串)用于规范化
pattern
的分词器。默认为顶级的的分词器。 -
use_field
(可选,字符串)如果指定,匹配该字段的间隔,而不是顶级的。
使用该字段的搜索分词器对模式进行规范化,除非单独指定了analyzer。
all_of
参数规则:
all_of规则返回跨越其他规则组合的匹配。
-
intervals
(Required, array of rule objects)要组合的规则数组。所有规则都必须在文档中产生一个匹配,以便与整个源进行匹配。
-
max_gaps
(可选,整数)匹配项之间的最大位置数。由规则产生的间隔比这个间隔更远的不被认为是匹配的。默认值为-1。
如果未指定或设置为-1,则匹配没有宽度限制。如果设置为0,则这些项必须出现在彼此旁边。
-
ordered
(可选,布尔值)如果为true,由规则产生的间隔应该按照指定的顺序出现。默认为false。
-
filter
(可选,interval过滤规则对象)用于过滤返回间隔的规则。
any_of
参数规则:
any_of规则返回由它的任何子规则产生的间隔。
-
intervals
(Required, array of rule objects)要匹配的规则数组。
-
filter
(可选,interval过滤规则对象)用于过滤返回间隔的规则。
filter
参数规则:
筛选规则根据查询返回间隔。有关示例,请参见filter示例。
-
after
(可选,查询对象)查询,返回过滤规则指定interval后的intervals。
-
before
(可选,查询对象)查询过滤规则中某个interval之前的intervals
-
contained_by
(可选,查询对象)用于返回过滤规则中某个interval所包含的intervals。
-
containing
(可选,查询对象)查询,用于返回包含过滤规则中的interval的intervals。
-
not_contained_by
(可选,查询对象)用于从过滤规则中返回不包含在某个interval的intervals。
-
not_containing
(可选,查询对象)用于返回过滤规则中不包含interval的intervals。
-
not_overlapping
(可选,查询对象)用于返回与过滤规则中interval不重叠的intervals。
-
overlapping
(可选,查询对象)用于返回与过滤规则中某个interval重叠的intervals。
-
script
(可选,脚本对象)返回匹配文档的脚本。这个脚本必须返回一个布尔值,true或false。有关示例,请参见脚本过滤器。
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 filter(脚本过滤)
您可以使用脚本根据interval的start position、end position和interval gap来过滤intervals。下面的过滤器脚本使用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查询总是最小化intervals,确保查询可以在线性时间内运行。这有时会导致出乎意料的结果,特别是在使用max_gaps限制或过滤器时,例如,以下面的查询为例,搜索短语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规则包含重叠的子规则的情况。特别是,如果其中一个规则是另一个规则的严格前缀,那么较长的规则永远无法匹配,这可能会在与max_gaps组合使用时引起意外。考虑以下查询,搜索紧跟着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
}
}
}
}
}
与直觉相反的是,这个查询不匹配文档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 } }
]
}
}
}
}
}
Match
返回与所提供的文本、数字、日期或布尔值匹配的文档。在匹配之前对所提供的文本进行分词。
match查询是执行全文搜索的标准查询,包括模糊匹配选项。
例如:
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "this is a test"
}
}
}
}
match的核心参数:
(必选,对象)要搜索的字段。
的参数:
-
query
(必选)您希望在中找到的文本,数字,布尔值或日期。
match查询在执行搜索之前分词所提供的任何文本。这意味着match查询可以在文本字段中搜索已分词的标记,而不是精确的term查询。
-
analyzer
(可选,字符串)用于将查询值中的文本转换为令牌的分词器。默认为映射到的索引时间分词器。如果没有映射分词器,则使用索引的默认分析器。
-
auto_generate_synonyms_phrase_query
(可选,布尔值)如果为真,匹配短语查询将自动为多词同义词创建。默认为true。
-
fuzziness
(可选,字符串)允许匹配的最大模糊距离。
-
max_expansions
(可选,整数)查询将扩展到的最大术语数。默认值为50。
-
prefix_length
(可选,整数)模糊匹配时保持开头字符不变的个数。默认值为0。
-
fuzzy_transpositions
(可选,boolean)如果为true,模糊匹配包括两个相邻字符的转置(ab→ba)。默认为true。
-
fuzzy_rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅重写参数。
如果模糊性参数不为0,匹配查询默认使用top_terms_blended_freqs_${max_expansions}的重写方法。
-
lenient
(可选,布尔值)如果为true,则忽略基于格式的错误,例如为数值字段提供文本查询值。默认为false。
-
operator
(可选,字符串)用于解释查询值中的文本的布尔逻辑。有效值为:
-
OR(Default)
例如,
capital of Hungary
查询值被解释为capital
ORof
ORHungary
-
AND
例如,
capital of Hungary
查询值将被分为capital
ANDof
ANDHungary
-
-
min_should_match
(可选,string)返回文档必须匹配的最小子句数。有关有效值和更多信息,请参阅minimum_should_match参数。
-
zero_terms_query
(可选,字符串)表示如果分析器删除所有令牌,例如在使用
stop
过滤器时,是否不返回任何文档。有效值为:-
none(Default)
如果分析器删除所有令牌,则不返回任何文档。
-
all
返回所有文档,类似于match_all查询。
-
Short request example(简短请求示例)
您可以通过组合和查询参数来简化匹配查询语法。例如:
GET /_search
{
"query": {
"match" : {
"message" : "this is a test"
}
}
}
match查询是如何工作的
match查询类型为布尔。这意味着分词所提供的文本,分词过程根据所提供的文本构造一个布尔查询。操作符参数可以设置为OR或AND来控制布尔子句(默认为或)。可以使用minimum_should_match
参数设置要匹配的可选should子句的最小数量。
例如:
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "this is a test",
"operator" : "and"
}
}
}
}
分词器可以设置为控制哪个分词器将对文本执行分词过程。它默认为字段显式映射定义或默认分词器。
可以将lenient
参数设置为true,以忽略由数据类型不匹配引起的异常,例如试图使用文本查询字符串查询数字字段。默认为false。
match查询中的Fuzziness
模糊性允许基于正在查询的字段类型进行模糊匹配。查看允许的设置模糊。
在这种情况下,可以设置prefix_length和max_expansions来控制模糊过程。如果设置了fuzzy选项,查询将使用top_terms_blendd_freqs_ ${max_expansions}作为重写方法,fuzzy_rewrite参数允许控制如何重写查询。
默认情况下允许模糊换位(ab→ba),但可以通过将fuzzy_transpositions设置为false来禁用。
模糊匹配不适用于具有同义词的术语或分词过程在同一位置产生多个标记的情况。在底层,这些术语被扩展为一个特殊的同义词查询,它混合了术语频率,不支持模糊扩展。
zero terms query
如果所使用的分词器像stop
过滤器一样删除查询中的所有令牌,则默认行为是根本不匹配任何文档。为了改变这一点,可以使用zero_terms_query选项,该选项接受none(默认值),而all则对应于match_all查询。
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "to be or not to be",
"operator" : "and",
"zero_terms_query": "all"
}
}
}
}
Cutoff frequency(截止频率)
7.3.0中已弃用。
这个选项可以省略,因为Match可以有效地跳过文档块,而不需要任何配置,前提是不跟踪总命中数
匹配查询支持cutoff_frequency,它允许指定绝对或相对文档频率,其中高频术语被移动到可选子查询中,并且仅在与操作符匹配的情况下,其中一个低频(低于截止值)术语或与操作符匹配的情况下,所有低频术语才会被评分。
该查询允许在运行时动态处理stopword,与域无关,不需要stopword文件。它可以防止对高频术语进行评分/迭代,并且只在较重要/较低频率的术语与文档匹配时才考虑这些术语。但是,如果所有查询项都在给定的cutoff_frequency以上,则查询将自动转换为纯连接(和)查询,以确保快速执行。
如果在0(包含)到1(不包含)的范围内,cutoff_frequency可以是相对于文档总数的,如果大于或等于1.0,则是绝对的。
下面是一个例子,显示了一个专门由stopwords组成的查询:
GET /_search
{
"query": {
"match" : {
"message" : {
"query" : "to be or not to be",
"cutoff_frequency" : 0.001
}
}
}
}
cutoff_frequency选项在每个分片级上操作。这意味着当在低文档数量的测试索引上尝试它时,您应该遵循相关性被打破中的建议。
Synonyms(同义)
匹配查询支持使用synonym_graph令牌过滤器进行多术语同义词扩展。使用此筛选器时,解析器为每个多术语同义词创建短语查询。例如,下面的同义词:"ny, new york"会产生: (ny OR ("new york"))
也可以用连词来匹配多个术语的同义词:
GET /_search
{
"query": {
"match" : {
"message": {
"query" : "ny city",
"auto_generate_synonyms_phrase_query" : false
}
}
}
}
上面的例子创建了一个布尔查询:
(ny OR (new AND york)) city
将文档与术语ny或连接词new和york匹配。默认情况下,参数auto_generate_synonyms_phrase_query设置为true。
Match boolean prefix query(前缀匹配查询)
match_bool_prefix查询分词其输入并根据术语构造bool查询。在术语查询中使用除最后一个以外的每个术语。最后一个词用于前缀查询。一个match_bool_prefix查询,例如
GET /_search
{
"query": {
"match_bool_prefix" : {
"message" : "quick brown f"
}
}
}
分词产生术语quick
,brown
,和f
类似于下面的bool查询:
GET /_search
{
"query": {
"bool" : {
"should": [
{ "term": { "message": "quick" }},
{ "term": { "message": "brown" }},
{ "prefix": { "message": "f"}}
]
}
}
}
match_bool_prefix
查询和match_phrase_prefix
查询之间的一个重要区别是,match_phrase_prefix
查询将其术语作为短语进行匹配,而match_bool_prefix
查询可以在任何位置匹配其术语。上面的match_bool_prefix
查询示例可以匹配一个包含quick brown fox的字段,但它也可以匹配brown fox quick。它还可以匹配一个包含术语quick、术语brown和出现在任何位置的以f开头的项的字段。
参数:
默认情况下,match_bool_prefix
查询的输入文本将使用分词器从查询字段的映射中分词。可以使用analyzer
参数配置不同的搜索分词器
GET /_search
{
"query": {
"match_bool_prefix" : {
"message": {
"query": "quick brown f",
"analyzer": "keyword"
}
}
}
}
Match_bool_prefix查询支持匹配查询中描述的minimum_should_match和操作符参数,将该设置应用于构造的bool查询。构造的bool查询中的子句数量在大多数情况下是通过分词查询文本产生的术语数量。
fuiness、prefix_length、max_expansions、fuzzy_transpositions和fuzzy_rewrite参数可以应用于为除最终项以外的所有项构造的term子查询。它们对为最终项构造的前缀查询没有任何影响。
Match phrase
match_phrase查询分词文本,并根据分词的文本创建短语查询。例如:
GET /_search
{
"query": {
"match_phrase" : {
"message" : "this is a test"
}
}
}
短语查询以任意顺序匹配可配置slop
(默认为0)以内的术语。转置项的斜率是2。
分词器可以设置为控制哪个分词器将对文本执行分词过程。它默认为字段显式映射定义,或默认搜索分词器,例如:
GET /_search
{
"query": {
"match_phrase" : {
"message" : {
"query" : "this is a test",
"analyzer" : "my_analyzer"
}
}
}
}
该查询还接受zero_terms_query,如match query中所述。
Match phrase prefix
返回包含所提供文本的单词的文档,顺序与所提供的相同。所提供文本的最后一个词被视为前缀,匹配以该词开头的任何单词。
例:
下面的搜索返回在message字段中包含quick brown f
开头的短语的文档。
应该匹配quick brown f
或two quick brown ferrets
但是不匹配the fox is quick and brown
GET /_search
{
"query": {
"match_phrase_prefix" : {
"message" : {
"query" : "quick brown f"
}
}
}
}
顶级参数:
(必选,对象)要搜索的字段。
参数
-
query
(Required, string)您希望在提供的中找到的文本。
match_phrase_prefix查询在执行搜索之前将任何提供的文本分词为令牌。本文的最后一个词被视为前缀,匹配以该词开头的任何单词。
-
analyzer
配置分词器。默认为映射到的索引时间分词器。如果没有映射分词器,则使用索引的默认分词器。
-
max_expansions
(可选,整数)查询值最后提供的项将扩展到的最大项数。默认值为50。
-
slop
(可选,整数)匹配令牌之间允许的最大位置数。默认值为0。转置项的斜率是2。
-
zero_tems_query
与match查询一致
使用匹配短语前缀查询自动完成搜索
虽然易于设置,但使用match_phrase_prefix查询自动完成搜索有时会产生令人困惑的结果。
例如,考虑查询字符串quick brown f。该查询通过创建quick和brown的短语查询来工作(即术语quick必须存在,并且后面必须有术语brown)。然后,它查看已排序的术语字典,查找以f开头的前50个术语,并将这些术语添加到短语查询中。
问题是,前50个术语可能不包括“fox”一词,因此“quick brown fox”一词将找不到。这通常不是问题,因为用户会继续输入更多字母,直到他们要找的单词出现。
Common tems query
7.3已经弃用,使用match查询代替
Query string
使用语法严格的解析器,根据提供的查询字符串返回文档。
该查询使用一种语法根据运算符(如and或NOT)解析和拆分所提供的查询字符串。然后,该查询在返回匹配的文档之前分别分析每个分割的文本。
可以使用query_string查询创建复杂的搜索,其中包括通配符、跨多个字段的搜索等等。虽然通用,但查询是严格的,如果查询字符串包含任何无效语法,则返回错误。
因为它会对任何无效的语法返回错误,所以我们不建议对搜索框使用query_string查询。
如果不需要支持查询语法,可以考虑使用匹配查询。如果需要查询语法的特性,可以使用不那么严格的simple_query_string查询。
例如:
在运行下面的搜索时,query_string查询将(new york city) OR (big apple)分成两部分:new york city和big apple。然后,内容字段的分词器在返回匹配文档之前将每个部分独立地转换为标记。因为查询语法没有使用空格作为操作符,所以将new york city按原样传递给分词程序。
GET /_search
{
"query": {
"query_string" : {
"query" : "(new york city) OR (big apple)",
"default_field" : "content"
}
}
}
query_string核心参数
-
query
(Required, string)要解析和用于搜索的查询字符串。请参阅本小节的字符串语法。
-
default_field
(可选,string)如果查询字符串中没有字段,则希望搜索的默认字段。
默认为index.query.default_field索引设置,其默认值为*。值提取符合术语查询条件的所有字段并过滤元数据字段。然后,如果没有指定前缀,则将所有提取的字段组合在一起构建查询。
一次可以查询的字段数量是有限制的。它由
indices.query.bool.max_clause_count
定义。Max_clause_count搜索设置,默认为1024。可在Elasticsearch配置文件中修改 -
allow_leading_wildcard
(可选,布尔值)如果为true,则通配符*和?允许作为查询字符串的第一个字符。默认为true。
-
anayler_wildcard
(可选,boolean)如果为true,查询将尝试分词查询字符串中的通配符。默认为false。
-
anayler
(可选,string)用于将查询字符串中的文本转换为令牌的分词器。默认为映射到default_field的索引时间分词器。如果没有映射分词器,则使用索引的默认分词器。
-
auto_generate_synonyms_phrase_query
(可选,布尔值)如果为真,匹配短语查询将自动为多词同义词创建。默认为true。有关示例,请参见同义词和query_string查询。
-
boost
(可选,浮点数)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
-
default_operator
(可选,string)如果没有指定操作符,则用于解释查询字符串中的文本的默认布尔逻辑。有效值为:
-
OR (Default)
例如
capital of hungary
被解释为capital
ORof
ORhungary
-
AND
例如
capital of hungary
被解释为capital
ANDof
ANDhungary
-
-
enable_position_increments
(可选,布尔值)如果为true,在query_string搜索构造的查询中启用位置增量。默认为true。
-
fields
(可选,array of strings)希望搜索的字段数组。
可以使用此参数查询跨多个字段进行搜索。请参见搜索多个字段。
-
fuzziness
(可选,字符串)允许匹配的最大编辑距离。有关有效值和更多信息,请参阅模糊性。
-
fuzzy_max_expansions
(可选,整数)查询展开进行模糊匹配的最大术语数。默认值为50。
-
fuzzy_prefix_length
(可选,整数)模糊匹配时保持开头字符不变的个数。默认值为0。
-
fuzzy_transpositions
(可选,boolean)如果为true,模糊匹配的编辑包括两个相邻字符的转置(ab→ba)。默认为true。
-
lenient
(可选,布尔值)如果为true,则忽略基于格式的错误,例如为数值字段提供文本值。默认为false。
-
max_determinized_states
(可选,整数)查询所需的最大自动机状态数。缺省值是10000。
Elasticsearch在内部使用Apache Lucene解析正则表达式。Lucene将每个正则表达式转换为包含许多确定状态的有限自动机。
您可以使用此参数来防止转换无意中消耗太多资源。要运行复杂的正则表达式,可能需要增加这个限制。
-
min_should_match
(可选,string)返回文档必须匹配的最小子句数。有关有效值和更多信息,请参阅minimum_should_match参数。有关示例,请参见minimum_should_match如何工作。
-
quote_analyzer
(可选,string)用于将查询字符串中的引用文本转换为令牌的分词器。默认为default_field映射的search_quote_analyzer。
对于引用的文本,此参数将覆盖analyzer参数中指定的分析器。
-
phrase_slop
(可选,整数)短语的匹配令牌之间允许的最大位置数。默认值为0。如果为0,则需要精确的短语匹配。转置项的斜率是2。
-
quote_field_suffix
(可选,string)在查询字符串中附加到引用文本的后缀。
可以使用此后缀使用不同的分析方法进行精确匹配。
-
rewrite
(可选,字符串)用于重写查询的方法。
-
time_zone
(可选,string) UTC (Coordinated Universal Time)偏移量或IANA时区,用于将查询字符串中的日期值转换为UTC。
有效值为ISO 8601 UTC偏移量,如+01:00或-08:00,IANA时区id,如America/Los_Angeles。
time_zone参数不影响now的日期数学值。now始终是当前系统时间(UTC)。但是,time_zone参数转换使用now和日期数学舍入计算的日期。例如,time_zone参数将转换为now/d的值。
字符串语法
查询字符串" mini-language "由query字符串和搜索API中的q查询字符串参数使用。
查询字符串被解析成一系列术语和操作符。一个术语可以是一个单词——quick或brown——也可以是一个短语,用双引号括起来——“quick brown”——它会以相同的顺序搜索短语中的所有单词。
操作符允许您自定义搜索-下面将解释可用的选项。
字段名
你可以在查询中指定要搜索的字段
-
查找
status
字段中包含active
status:active
-
title
字段包含quick
或者brown
title:(quick OR brown)
-
author
字段中包含确切的短语john smith
author:"john smith"
-
first name
字段包含Alice
,需要使用反斜杠转义空格first\ name:Alice
-
所有的字段例如
book.content
,book.date
,book.type
要包含quick
或者brown
,注意需要使用反斜杠转义*book.\*:(quick OR brown)
-
字段title有非空的值
_exists_:title
通配符
通配符搜索可以在单个术语上运行,使用?替换单个字符,*替换零个或多个字符:
请注意,通配符查询可能会使用大量内存,并且性能非常差——只需考虑需要查询多少项才能匹配query string“a* b* c*”即可。
纯通配符*被重写为存在查询以提高效率。因此,通配符“field:*”将匹配具有如下空值的文档:
{ "field": "" }
并且如果字段缺失或设置为显式空值,将不匹配,如下所示:
{ "field": null }
允许在单词的开头使用通配符(例如“*ing”)特别重,因为需要检查索引中的所有项,以防它们匹配。前导通配符可以通过将allow_leading_wildcard设置为false来禁用。
只有在字符级别上操作的部分分词链被应用。例如,如果分词器同时执行小写字母和词干,那么只会应用小写字母:对缺少某些字母的单词执行词干是错误的。
通过将analyze_wildcard设置为true,将分析以*结尾的查询,并根据不同的令牌构建布尔查询,确保在前N-1个令牌上进行精确匹配,并在最后一个令牌上进行前缀匹配。
正则表达式
正则表达式模式可以通过用正斜杠(“/”)来嵌入到查询字符串中:
name:/joh?n(ath[oa]n)/
支持的正则表达式将在正则表达式使用章节介绍
allow_leading_wildcard参数对正则表达式没有任何控制。如下所示的查询字符串将迫使Elasticsearch访问索引中的每个词:
/.*n/
模糊性(Fuzziness)
我们可以使用“fuzzy”操作符搜索与我们的搜索词相似但不完全相同的词:
quikc~
brwn~
foks~
它使用Damerau-Levenshtein距离来查找所有最多有两次更改的项,其中更改是插入、删除或替换单个字符,或调换两个相邻字符。
默认的编辑距离是2,但是编辑距离为1应该足以捕获80%的人类拼写错误。它可以指定为:
quikc~1
近似搜索(Proximity searches)
短语查询(例如“john smith”)期望所有的词都以完全相同的顺序出现,而接近性查询允许指定的词相距更远或以不同的顺序出现。与模糊查询可以指定单词中字符的最大编辑距离相同,接近搜索允许我们指定短语中单词的最大编辑距离:
"fox quick"~5
字段中的文本与查询字符串中指定的原始顺序越接近,则认为该文档的相关性越高。当与上面的示例查询进行比较时,短语“quick fox”将被认为比“quick brown fox”更相关。
范围(Ranges)
可以为日期、数字或字符串字段指定范围。包含边界用方括号[min TO max]指定,不包括边界用花括号{min TO max}指定。
-
包含2012年的每一天
date:[2021-01-01 TO 2021-12-31]
-
搜索数字在1~5
number:[1 TO 5]
-
alpha和omega之间的标签,不包括alpha和omega:
tag:{alpha TO omega}
-
搜索大于10的数
number:[10 TO *]
-
搜索2012之前的时间
date:{* TO 2012-01-01}
大括号和方括号可以组合
-
从1到5的数字但是不包括5
number:[1 TO 5}
单面无界的范围可以使用以下语法:
age:>10
age:>=10
age:<10
age:<=10
为了用简化的语法组合上界和下界,你需要用and操作符连接两个子句:
age:(>=10 AND <20)
age:(+>=10 +<20)
查询字符串中范围的解析可能很复杂,而且容易出错。使用显式范围查询要可靠得多。
分数提升(Boosting)
使用提升运算符^使一个术语比另一个术语更相关。例如,如果我们想找到所有关于fox的文档,但我们对quick foxes特别感兴趣:
quick^2 fox
默认的升压值是1,但可以是任何正浮点数。0到1之间的提升降低了相关性。
boost也可以应用于短语或组:
“john smith”^2
(foo bar)^4
布尔逻辑(boolean operator)
默认情况下,所有术语都是可选的,只要有一个术语匹配。搜索foo bar baz可以找到任何包含一个或多个foo、bar或baz的文档。我们已经讨论了上面的default_operator,它允许您强制要求所有的术语,但是还可以在查询字符串本身中使用布尔操作符来提供更多的控制。
首选操作符是+(此项必须出现)和-(此项不能出现)。所有其他条款都是可选的。例如,这个查询:
quick brown +fox -news
解释:
- 必须有fox
- 不能有news
- quick与brown是可选的,他们的存在增加了相关性
我们熟悉的布尔运算符AND, OR和NOT(也被写成&&,||和!)也被支持,但注意它们不遵守通常的优先级规则,所以当多个运算符一起使用时,应该使用括号。例如,前面的查询可以重写为:
((quick AND fox) OR (brown AND fox) ) AND NOT news
该表单现在正确地复制了原始查询的逻辑,但相关性评分与原始查询几乎没有相似之处。
相反,使用match查询重写的相同查询将如下所示:
{
"bool": {
"must": { "match": "fox" },
"should": { "match": "quick brown" },
"must_not": { "match": "news" }
}
}
分组
多个术语或子句可以用圆括号组合在一起,形成子查询:
(quick OR brown) AND fox
组可以用来针对特定的字段,或者提升子查询的结果:
status:(active OR pending) title:(full text search)^2
保留字符
如果您需要在查询本身中使用任何作为操作符(而不是作为操作符)的字符,那么您应该使用前导反斜杠来转义它们。例如,要搜索(1+1)=2,您需要将查询写成(1+1)=2。当使用JSON作为请求体时,前面两个反斜杠(\)是必需的;反斜杠是JSON字符串中的保留转义字符。
GET /twitter/_search
{
"query" : {
"query_string" : {
"query" : "kimchy\\!",
"fields" : ["user"]
}
}
}
保留字符有:
+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
如果不能正确转义这些特殊字符,可能会导致语法错误,从而阻止查询运行。
<和>根本不能转义。阻止它们尝试创建范围查询的唯一方法是将它们从查询字符串中完全删除。
空格和空查询
空格不被认为是运算符。
如果查询字符串为空或只包含空白,则查询将产生空结果集。
避免对嵌套文档使用query_string查询
Query_string搜索不返回嵌套文档。要搜索嵌套文档,请使用嵌套查询。
多字段搜索
可以使用fields参数跨多个字段执行query_string搜索。
对多个字段运行query_string查询的想法是将每个查询项展开为一个OR子句,如下所示:
field1:query_term OR field2:query_term | ...
例如:
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name"],
"query" : "this AND that"
}
}
}
与上面相同的查询为:
GET /_search
{
"query": {
"query_string": {
"query": "(content:this OR name:this) AND (content:that OR name:that)"
}
}
}
由于从单个搜索词生成了几个查询,因此使用带有tie_breaker的dis_max查询自动组合它们。例如(使用^5表示法,名称增加了5):
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name^5"],
"query" : "this AND that OR thus",
"tie_breaker" : 0
}
}
}
简单的通配符还可以用于在文档的特定内部元素中搜索。例如,如果我们有一个包含多个字段的city对象(或者包含多个字段的内部对象),我们可以自动搜索所有“city”字段:
GET /_search
{
"query": {
"query_string" : {
"fields" : ["city.*"],
"query" : "this AND that OR thus"
}
}
}
另一种选择是在查询字符串本身提供通配符字段搜索(正确转义*符号),例如:city.*:something:
GET /_search
{
"query": {
"query_string" : {
"query" : "city.\\*:(this AND that OR thus)"
}
}
}
由于(反斜杠)是json字符串中的一个特殊字符,因此需要转义,因此上面query_string中的两个反斜杠。
fields参数还可以包括基于模式的字段名,允许自动展开到相关字段(包括动态引入的字段)。例如:
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name.*^5"],
"query" : "this AND that OR thus"
}
}
}
用于多个字段搜索的附加参数
当对多个字段运行query_string查询时,支持以下附加参数。
type
(可选,字符串)确定查询如何匹配文档并为文档评分。有效值为:
-
best_field(Default)
查找匹配任何字段的文档,并使用任何匹配字段中的最高_score。看best_fields。
-
bool_prefix
在每个字段上创建一个match_bool_prefix查询,并结合每个字段的_score。
-
cross_fields
使用相同的分析程序处理字段,就好像它们是一个大字段一样。在任何领域查找每个单词
-
most_fields
查找匹配任何字段的文档,并结合每个字段的_score。
-
phrase
对每个字段运行match_phrase查询,并使用最佳字段的_score。
-
phrase_prefix
对每个字段运行match_phrase_prefix查询,并使用最佳字段的_score。
根据类型值,可以使用其他顶级multi_match参数。
同义词和query_string查询
query_string查询使用synonym_graph令牌过滤器支持多术语同义词扩展。使用此筛选器时,解析器为每个多术语同义词创建短语查询。例如,下面的同义词:ny, new york会产生:
(ny OR ("new york"))
也可以用连词来匹配多个术语的同义词:
GET /_search
{
"query": {
"query_string" : {
"default_field": "title",
"query" : "ny city",
"auto_generate_synonyms_phrase_query" : false
}
}
}
上面的例子创建了一个布尔查询:
(ny OR (new AND york)) city
将文档与术语ny或连接词new和york匹配。默认情况下,参数auto_generate_synonyms_phrase_query设置为true。
minimum_should_match如何工作
query_string围绕每个操作符拆分查询,为整个输入创建一个布尔查询。您可以使用minimum_should_match来控制结果查询中应该匹配多少个“should”子句。
GET /_search
{
"query": {
"query_string": {
"fields": [
"title"
],
"query": "this that thus",
"minimum_should_match": 2
}
}
}
上面的例子创建了一个布尔查询:
(title:this title:that title:thus)~2
在单个字段标题中匹配至少两个术语this、That或thus的文档
minimum_should_match如何适用于多个字段
GET /_search
{
"query": {
"query_string": {
"fields": [
"title",
"content"
],
"query": "this that thus",
"minimum_should_match": 2
}
}
}
上面的例子创建了一个布尔查询:
((content:this content:that content:thus) | (title:this title:that title:thus))
在字段标题和内容上使用Max来匹配文档。这里不能应用minimum_should_match参数。
GET /_search
{
"query": {
"query_string": {
"fields": [
"title",
"content"
],
"query": "this OR that OR thus",
"minimum_should_match": 2
}
}
}
添加显式操作符将迫使将每个术语视为单独的子句。
上面的例子创建了一个布尔查询:
((content:this | title:this) (content:that | title:that) (content:thus | title:thus))~2
它匹配了三个“应该”子句中的至少两个,每个子句都由每个术语的字段上的Max分离组成。
minimum_should_match如何用于跨域搜索
类型字段中的cross_fields值表示在分析输入时,具有相同分析器的字段被分组在一起。
GET /_search
{
"query": {
"query_string": {
"fields": [
"title",
"content"
],
"query": "this OR that OR thus",
"type": "cross_fields",
"minimum_should_match": 2
}
}
}
上面的例子创建了一个布尔查询:
(blended(terms:[field2:this, field1:this]) blended(terms:[field2:that, field1:that]) blended(terms:[field2:thus, field1:thus]))~2
它将文档与三个按术语混合查询中的至少两个相匹配。
Simple query string
使用语法有限但容错的解析器,根据提供的查询字符串返回文档。
此查询使用简单的语法根据特殊操作符解析并将提供的查询字符串拆分为术语。然后,该查询在返回匹配文档之前独立地分析每个术语。
虽然它的语法比query_string查询更有限,但simple_query_string查询不会因语法无效而返回错误。相反,它会忽略查询字符串的任何无效部分。
例如:
GET /_search
{
"query": {
"simple_query_string" : {
"query": "\"fried eggs\" +(eggplant | potato) -frittata",
"fields": ["title^5", "body"],
"default_operator": "and"
}
}
}
simple_query_string
核心参数
-
query
(Required, string)要解析和用于搜索的查询字符串。参见简单查询字符串语法。
-
fields
(可选,array of strings)希望搜索的字段数组。
该字段接受通配符表达式。还可以使用插入符号(^)符号提高与特定字段匹配的相关性分数。有关示例,请参见fields参数中的通配符和每个字段的提升。
默认为index.query.default_field索引设置,其默认值为*。值提取符合术语查询条件的所有字段并过滤元数据字段。然后,如果没有指定前缀,则将所有提取的字段组合在一起构建查询。
一次可以查询的字段数量是有限制的。它由indices.query.bool.max_clause_count定义。Max_clause_count搜索设置,默认为1024。可在配置文件中修改
-
default_operator
(可选,string)如果没有指定操作符,则用于解释查询字符串中的文本的默认布尔逻辑。有效值为:
- OR
- AND
-
all_fields
(可选,布尔值)如果为true,搜索索引字段映射中的所有可搜索字段。
-
analyze_wildcard
(可选,boolean)如果为true,查询将尝试分词查询字符串中的通配符。默认为false。
-
analyzer
(可选,string)用于将查询字符串中的文本转换为令牌的分析器。默认为映射到default_field的索引时间分析器。如果没有映射分析器,则使用索引的默认分析器。
-
auto_generate_synonyms_phrase_query
(可选,布尔值)如果为真,匹配短语查询将自动为多词同义词创建。默认为true。有关示例,请参见同义词。
-
flags
(可选,string)用于简单查询字符串语法的启用操作符列表。默认为ALL(所有操作符)。请参阅限制运算符了解有效值。
-
fuzzy_max_expansions
(可选,整数)查询展开进行模糊匹配的最大术语数。默认值为50。
-
fuzzy_prefix_length
(可选,整数)模糊匹配时保持开头字符不变的个数。默认值为0。
-
fuzzy_transpositions
(可选,boolean)如果为true,模糊匹配的编辑包括两个相邻字符的转置(ab→ba)。默认为true。
-
lenient
(可选,布尔值)如果为true,则忽略基于格式的错误,例如为数值字段提供文本值。默认为false。
-
minimum_should_match
(可选,string)返回文档必须匹配的最小子句数。有关有效值和更多信息,请参阅minimum_should_match参数。
-
quote_field_suffix
(可选,string)在查询字符串中附加到引用文本的后缀。
可以使用此后缀使用不同的分析方法进行精确匹配。参见混合精确搜索和词干。
简单查询字符串语法
simple_query_string查询支持以下操作符:
+
:符号与运算|
:符号与运算-
:对单个令牌求反"
:包装多个标记,以表示要搜索的短语*
: 在一个词的末尾表示一个前缀查询()
:表示优先级~N
: 字后表示编辑距离(模糊性)~N
: 短语后表示slop amount
若要字面上使用这些字符之一,请使用前面的反斜杠()进行转义。
根据default_operator值的不同,这些操作符的行为可能有所不同。例如:
GET /_search
{
"query": {
"simple_query_string" : {
"fields" : ["content"],
"query" : "foo bar -baz"
}
}
}
此搜索旨在仅返回包含foo或bar且不包含baz的文档。然而,由于OR的default_operator,此搜索实际上返回包含foo或bar的文档以及任何不包含baz的文档。要按预期返回文档,请将查询字符串更改为foo bar ±baz。
限制运算符
您可以使用flags参数限制简单查询字符串语法所支持的操作符。
若要显式地只启用特定的操作符,请使用|分隔符。例如,flags值为OR|AND|PREFIX禁用除OR、AND和PREFIX之外的所有操作符。
GET /_search
{
"query": {
"simple_query_string" : {
"query" : "foo | bar + baz*",
"flags" : "OR|AND|PREFIX"
}
}
}
flags有效的值:
-
ALL(Default)
启用所有可选操作符。
-
AND
启用+ AND运算符。
-
ESCAPE
启用\作为转义字符。
-
FUZZY
在单词后启用~N操作符,其中N是一个整数,表示允许进行匹配的编辑距离
-
NEAR
启用~N操作符,位于短语之后,其中N是匹配令牌之间允许的最大位置数。与SLOP同义。
-
NONE
禁用所有操作符。
-
NOT
启用- NOT操作符。
-
OR
启用|或操作符。
-
PHRASE
启用用于搜索短语的“引号操作符”。
-
PRECEDENCE
启用(and)操作符来控制操作符优先级。
-
PREFIX
启用*前缀运算符。
-
SLOP
启用~N操作符,位于短语之后,其中N是匹配令牌之间允许的最大位置数。NEAR的同义词。
-
WHITESPACE
启用空格作为分割字符。
fields参数中的通配符和每个字段的提升
字段可以用通配符指定,例如:
GET /_search
{
"query": {
"simple_query_string" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ]
}
}
}
单个字段可以使用插入符号(^)符号进行提升:
GET /_search
{
"query": {
"simple_query_string" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ]
}
}
}
同义词
simple_query_string查询使用synonym_graph令牌过滤器支持多术语同义词扩展。使用此筛选器时,解析器为每个多术语同义词创建短语查询。例如,下面的同义词:"ny, new york"会产生:
(ny OR ("new york"))
也可以用连词来匹配多个术语的同义词:
GET /_search
{
"query": {
"simple_query_string" : {
"query" : "ny city",
"auto_generate_synonyms_phrase_query" : false
}
}
}
上面的例子创建了一个布尔查询:
(ny OR (new AND york)) city)
将文档与术语ny或连接词new和york匹配。默认情况下,参数auto_generate_synonyms_phrase_query设置为true。
地理位置查询(Geo queryies)
暂不介绍
加入查询(Joining queryes)
在像Elasticsearch这样的分布式系统中执行完全sql风格的连接是非常昂贵的。相反,Elasticsearch提供了两种形式的连接,设计用于水平扩展。
-
nested query
文档可以包含嵌套类型的字段。这些字段用于为对象数组建立索引,其中每个对象都可以作为一个独立的文档进行查询(使用嵌套查询)。
-
has_child
和has_parent
查询连接字段关系可以存在于单个索引中的文档之间。has_child查询返回子文档与指定查询匹配的父文档,而has_parent查询返回父文档与指定查询匹配的子文档。
另请参阅术语查询中的术语查找机制,该机制允许您从另一个文档中包含的值构建术语查询。
嵌套查询(Nested)
包装另一个查询以搜索嵌套字段。
嵌套查询搜索嵌套字段对象,就好像它们被索引为单独的文档一样。如果对象与搜索匹配,嵌套查询将返回根父文档。
创建索引
要使用嵌套查询,你的索引必须包含嵌套映射
PUT /my_index
{
"mappings" : {
"properties" : {
"obj1" : {
"type" : "nested"
}
}
}
}
查询示例:
GET /my_index/_search
{
"query": {
"nested" : {
"path" : "obj1",
"query" : {
"bool" : {
"must" : [
{ "match" : {"obj1.name" : "blue"} },
{ "range" : {"obj1.count" : {"gt" : 5}} }
]
}
},
"score_mode" : "avg"
}
}
}
嵌套查询核心参数:
-
path
(Required, string)要搜索的嵌套对象的路径。
-
query
(必选,查询对象)您希望在路径中嵌套对象上运行的查询。如果对象与搜索匹配,嵌套查询将返回根父文档。
您可以使用包含完整路径的点符号搜索嵌套字段,例如obj1.name。
自动支持和检测多级嵌套,从而导致内部嵌套查询自动匹配相关的嵌套级别,而不是根,如果它存在于另一个嵌套查询中。
具体请查看本小节多级嵌套查询
-
score_mode
(可选,字符串)指示匹配子对象的分数如何影响根父文档的相关性分数。有效值为:
-
avg(Default)
使用所有匹配子对象的平均相关性得分。
-
max
使用所有匹配子对象中相关度最高的对象。
-
min
使用所有匹配子对象的最低相关性得分。
-
none
不要使用匹配子对象的相关性分数。查询将父文档赋值为0。
-
sum
将所有匹配子对象的相关性得分相加。
-
-
ignore_unmapped
(可选,布尔型)是否忽略未映射的路径,不返回任何文档,而是返回一个错误。默认为false。
如果为false,如果路径是未映射的字段,Elasticsearch将返回一个错误。
可以使用该参数查询多个不包含字段路径的索引。
多级嵌套查询
要了解多级嵌套查询是如何工作的,首先需要一个具有嵌套字段的索引。下面的请求用嵌套的make和model字段为驱动程序索引定义映射。
PUT /drivers
{
"mappings" : {
"properties" : {
"driver" : {
"type" : "nested",
"properties" : {
"last_name" : {
"type" : "text"
},
"vehicle" : {
"type" : "nested",
"properties" : {
"make" : {
"type" : "text"
},
"model" : {
"type" : "text"
}
}
}
}
}
}
}
}
接下来,将一些文档索引到drivers索引
PUT /drivers/_doc/1
{
"driver" : {
"last_name" : "McQueen",
"vehicle" : [
{
"make" : "Powell Motors",
"model" : "Canyonero"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
PUT /drivers/_doc/2?refresh
{
"driver" : {
"last_name" : "Hudson",
"vehicle" : [
{
"make" : "Mifune",
"model" : "Mach Five"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
现在可以使用多级嵌套查询来根据make和model字段匹配文档。
GET /drivers/_search
{
"query" : {
"nested" : {
"path" : "driver",
"query" : {
"nested" : {
"path" : "driver.vehicle",
"query" : {
"bool" : {
"must" : [
{ "match" : { "driver.vehicle.make" : "Powell Motors" } },
{ "match" : { "driver.vehicle.model" : "Canyonero" } }
]
}
}
}
}
}
}
}
搜索请求返回以下响应:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.7349272,
"hits" : [
{
"_index" : "drivers",
"_type" : "_doc",
"_id" : "1",
"_score" : 3.7349272,
"_source" : {
"driver" : {
"last_name" : "McQueen",
"vehicle" : [
{
"make" : "Powell Motors",
"model" : "Canyonero"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
}
]
}
}
有子查询(Has child)
返回其父文档,其子文档与所提供的查询匹配。您可以使用连接字段映射在同一索引中的文档之间创建父子关系。
因为它执行连接,所以has_child比其他查询慢。它的性能随着指向唯一父文档的匹配子文档数量的增加而下降。搜索中的每个has_child查询都会显著增加查询时间。
如果您关心查询性能,请不要使用此查询。如果需要使用has_child查询,请尽可能少地使用它。
创建索引
要使用has_child查询,索引必须包含join字段映射。例如:
PUT /my_index
{
"mappings": {
"properties" : {
"my-join-field" : {
"type" : "join",
"relations": {
"parent": "child"
}
}
}
}
}
查询示例:
GET /_search
{
"query": {
"has_child" : {
"type" : "child",
"query" : {
"match_all" : {}
},
"max_children": 10,
"min_children": 2,
"score_mode" : "min"
}
}
}
has_child查询核心参数:
-
type
(必选,字符串)映射到join字段的子关系的名称。
-
query
(必选,查询对象)希望在类型字段的子文档上运行的查询。如果子文档与搜索匹配,则查询返回父文档。
-
ignore_unmapped
(可选,布尔型)是否忽略未映射的类型,不返回任何文档而不是错误。默认为false。
如果为false, Elasticsearch将在类型未映射时返回一个错误。
可以使用该参数查询多个可能不包含该类型的索引。
-
max_children
(可选,整数)返回的父文档允许匹配查询的最大子文档数。如果父文档超过此限制,则从搜索结果中排除。
-
min_children
(可选,整数)匹配查询所需的最小子文档数,以匹配返回父文档的查询。如果父文档不符合此限制,将从搜索结果中排除。
-
score_mode
(可选,字符串)指示匹配子文档的分数如何影响根父文档的相关性分数。有效值为:
-
none(默认)
不要使用匹配子文档的相关性分数。查询将父文档赋值为0。
-
avg
使用所有匹配子对象的平均相关性得分。
-
max
使用所有匹配子对象中相关度最高的对象。
-
min
使用所有匹配子对象的最低相关性得分。
-
sum
将所有匹配子对象的相关性得分相加。
-
排序
您不能使用标准排序选项对has_child查询的结果进行排序。
如果您需要根据子文档中的字段对返回的文档排序,请使用function_score查询并根据_score排序。例如,下面的查询根据子文档的click_count字段对返回的文档进行排序。
GET /_search
{
"query": {
"has_child" : {
"type" : "child",
"query" : {
"function_score" : {
"script_score": {
"script": "_score * doc['click_count'].value"
}
}
},
"score_mode" : "max"
}
}
}
有父查询(Has parent)
返回其父文档与提供的查询相匹配的子文档。您可以使用join
字段映射在同一索引中的文档之间创建父子关系。
因为它执行连接,所以has_parent查询比其他查询慢。它的性能随着匹配父文档数量的增加而降低。搜索中的每个has_parent查询都会显著增加查询时间。
创建索引
要使用has_parent查询,索引必须包含join
字段映射。例如:
PUT /my-index
{
"mappings": {
"properties" : {
"my-join-field" : {
"type" : "join",
"relations": {
"parent": "child"
}
},
"tag" : {
"type" : "keyword"
}
}
}
}
查询示例:
GET /my-index/_search
{
"query": {
"has_parent" : {
"parent_type" : "parent",
"query" : {
"term" : {
"tag" : {
"value" : "Elasticsearch"
}
}
}
}
}
}
has_parent核心参数:
-
parent_type
(必选,字符串)映射到join字段的父关系的名称。
-
query
(必选,查询对象)希望在parent_type字段的父文档上运行的查询。如果父文档与搜索匹配,则查询返回其子文档。
-
score
(可选,布尔型)指示匹配父文档的相关性评分是否聚合到其子文档中。默认为false。
如果为false, Elasticsearch将忽略父文档的相关性评分。Elasticsearch还为每个子文档分配了一个与查询的boost相等的相关性分数,默认值为1。
如果为真,则匹配父文档的相关性得分将聚合到其子文档的相关性得分中。
-
ignore_unmapped
(可选,boolean)是否忽略未映射的parent_type,不返回任何文档而不是错误。默认为false。
如果为false,如果parent_type未映射,Elasticsearch将返回一个错误。
可以使用该参数查询多个不包含parent_type的索引。
排序
不能使用标准排序选项对has_parent查询的结果进行排序。
如果您需要根据父文档中的字段对返回的文档排序,请使用function_score查询并根据_score排序。例如,下面的查询根据父文档的view_count字段对返回的文档进行排序。
GET /_search
{
"query": {
"has_parent" : {
"parent_type" : "parent",
"score" : true,
"query" : {
"function_score" : {
"script_score": {
"script": "_score * doc['view_count'].value"
}
}
}
}
}
}
Parent ID Query
返回连接到特定父文档的子文档。您可以使用join字段映射在同一索引中的文档之间创建父子关系。
创建索引
要使用parent_id查询,索引必须包含连接字段映射。要了解如何为parent_id查询设置索引,请尝试以下示例。
1,创建带有连接字段映射的索引
PUT /my-index
{
"mappings": {
"properties" : {
"my-join-field" : {
"type" : "join",
"relations": {
"my-parent": "my-child"
}
}
}
}
}
2,索引ID为1的父文档。
PUT /my-index/_doc/1?refresh
{
"text": "This is a parent document.",
"my-join-field": "my-parent"
}
3,索引父文档的子文档。
PUT /my-index/_doc/2?routing=1&refresh
{
"text": "This is a child document.",
"my_join_field": {
"name": "my-child",
"parent": "1"
}
}
查询示例
下面的搜索为ID为1的父文档返回子文档。
GET /my-index/_search
{
"query": {
"parent_id": {
"type": "my-child",
"id": "1"
}
}
}
parent_id的核心参数:
-
type
(必选,字符串)映射到join字段的子关系的名称。
-
id
(Required, string)父文档的ID。查询将返回该父文档的子文档。
-
ignore_unmapped
(可选,布尔型)是否忽略未映射的类型,不返回任何文档而不是错误。默认为false。
如果为false, Elasticsearch将在类型未映射时返回一个错误。
可以使用该参数查询多个可能不包含该类型的索引。
查询全部(Match all)
最简单的查询,它匹配所有文档,所有文档的_score为1.0。
GET /_search
{
"query": {
"match_all": {}
}
}
_score可以通过boost参数改变:
GET /_search
{
"query": {
"match_all": { "boost" : 1.2 }
}
}
Match None query
这与match_all查询相反,后者不匹配任何文档。
GET /_search
{
"query": {
"match_none": {}
}
}
范围查询(Span query)
跨度查询是低级位置查询,它提供了对指定术语的顺序和接近度的专家控制。它们通常用于实现对法律文件或专利的非常具体的查询。
只允许在外层span查询上设置boost。复合span查询(如span_near)仅使用内span查询的匹配span列表来查找它们自己的span,然后使用该span生成一个分数。从不在内跨度查询上计算分数,这就是不允许提升的原因:它们只影响计算分数的方式,而不影响跨度。
Span查询不能与非Span查询混合使用(span_multi查询除外)。
该组中的查询是:
-
span_containing
query接受span查询列表,但只返回与第二个span查询匹配的span
-
field_masking_span
query允许像span-near或span-or跨不同字段的查询。
-
span_first
query接受另一个span查询,其匹配项必须出现在字段的前N个位置内。
-
span_multi
query包装term、range、prefix、wildcard、regexp或fuzzy查询。
-
span_near
query接受多个span查询,这些查询的匹配必须在彼此指定的距离内,并且顺序可能相同。
-
span_not
query包装另一个span查询,并排除与该查询匹配的任何文档。
-
span_or
query组合多个span查询—返回与任何指定查询匹配的文档。
-
span_term
query相当于term查询,但用于其他span查询。
-
span_within
query一个span查询的结果返回的长度是它的span在其他span查询列表返回的span范围内。
Span containing query
返回包含另一个span查询的匹配项。包含查询的span映射到Lucene SpanContainingQuery。这里有一个例子:
GET /_search
{
"query": {
"span_containing" : {
"little" : {
"span_term" : { "field1" : "foo" }
},
"big" : {
"span_near" : {
"clauses" : [
{ "span_term" : { "field1" : "bar" } },
{ "span_term" : { "field1" : "baz" } }
],
"slop" : 5,
"in_order" : true
}
}
}
}
}
big和little子句可以是任何span类型的查询。返回包含从小到大的匹配span。
Span field masking query
包装器允许跨查询通过放置其搜索字段来参与复合单字段跨查询。span字段屏蔽查询映射到Lucene的SpanFieldMaskingQuery
这可以用于支持类似span-near或span-or跨不同字段的查询,这通常是不允许的。
当相同的内容被多个分词器索引时,跨字段屏蔽查询与多字段一起使用是非常宝贵的。例如,我们可以用标准分词器将文本分解为单词,再用英语分词器将单词分解为词根形式来索引一个字段。
GET /_search
{
"query": {
"span_near": {
"clauses": [
{
"span_term": {
"text": "quick brown"
}
},
{
"field_masking_span": {
"query": {
"span_term": {
"text.stems": "fox"
}
},
"field": "text"
}
}
],
"slop": 5,
"in_order": false
}
}
}
注意:当span字段屏蔽查询返回屏蔽字段时,将使用提供的字段名的规范进行评分。这可能会导致意想不到的得分行为。
Span first query
匹配范围接近字段的开头。span第一个查询映射到Lucene SpanFirstQuery。这里有一个例子:
GET /_search
{
"query": {
"span_first" : {
"match" : {
"span_term" : { "user" : "kimchy" }
},
"end" : 3
}
}
}
match子句可以是任何其他span类型的查询。end控制查询中允许的最大结束位置。
Span multi-term query
span_multi查询允许您将多项查询(通配符、模糊、前缀、范围或regexp查询之一)包装为span查询,因此它可以嵌套。例子:
GET /_search
{
"query": {
"span_multi":{
"match":{
"prefix" : { "user" : { "value" : "ki" } }
}
}
}
}
boost也可以与查询相关联:
GET /_search
{
"query": {
"span_multi":{
"match":{
"prefix" : { "user" : { "value" : "ki", "boost" : 1.08 } }
}
}
}
}
如果匹配查询的词汇数量超过布尔查询限制(默认为1024),Span_multi查询将遇到太多子句失败。为了避免无界展开,可以将多术语查询的重写方法设置为top_terms_* rewrite。或者,如果您只在前缀查询上使用span_multi,则可以激活文本字段的index_prefixes字段选项。这将把字段上的任何前缀查询重写为与索引前缀匹配的单个术语查询。
Span near query
匹配彼此接近的跨度。可以指定slop,中间未匹配位置的最大数量,以及是否要求匹配是有序的。span_near查询映射到Lucene SpanNearQuery。这里有一个例子:
GET /_search
{
"query": {
"span_near" : {
"clauses" : [
{ "span_term" : { "field" : "value1" } },
{ "span_term" : { "field" : "value2" } },
{ "span_term" : { "field" : "value3" } }
],
"slop" : 12,
"in_order" : false
}
}
}
子元素是一个或多个其他span类型查询的列表,而slop控制允许的中间不匹配位置的最大数量。
Span not query
删除与另一个span查询重叠的匹配,或在另一个SpanQuery之前的x令牌(由参数pre控制)或在另一个SpanQuery之后的y令牌(由参数post控制)内的匹配。span not查询映射到Lucene SpanNotQuery。这里有一个例子:
GET /_search
{
"query": {
"span_not" : {
"include" : {
"span_term" : { "field1" : "hoya" }
},
"exclude" : {
"span_near" : {
"clauses" : [
{ "span_term" : { "field1" : "la" } },
{ "span_term" : { "field1" : "hoya" } }
],
"slop" : 0,
"in_order" : true
}
}
}
}
}
包含和排除子句可以是任何跨度类型的查询。include子句是筛选匹配的span查询,exclude子句是span查询,其匹配不能与返回的匹配重叠。
在上面的例子中,除了前面有la的文档外,所有带有术语hoya的文档都被过滤了。
其他顶级选项:
-
pre
如果在inculde span之前设置令牌数量,则不能与exclude span重叠。默认值为0。
-
post
如果设置include span之后的令牌数量不能与exclude span重叠。默认值为0。
-
dist
如果设置了include span内的令牌数量,则不能与exculde span重叠。相当于设置pre和post。
Span or query
匹配其span子句的并集。span_or查询映射到Lucene SpanOrQuery。这里有一个例子:
GET /_search
{
"query": {
"span_or" : {
"clauses" : [
{ "span_term" : { "field" : "value1" } },
{ "span_term" : { "field" : "value2" } },
{ "span_term" : { "field" : "value3" } }
]
}
}
}
子元素是一个或多个其他span类型查询的列表。
Span term query
匹配包含一个词的span。span_term查询映射到Lucene SpanTermQuery。这里有一个例子:
GET /_search
{
"query": {
"span_term" : { "user" : "kimchy" }
}
}
boost也可以与查询相关联:
GET /_search
{
"query": {
"span_term" : { "user" : { "value" : "kimchy", "boost" : 2.0 } }
}
}
或者
GET /_search
{
"query": {
"span_term" : { "user" : { "term" : "kimchy", "boost" : 2.0 } }
}
}
Span within query
返回包含在另一个span查询中的匹配项。span_within query映射到Lucene SpanWithinQuery。这里有一个例子:
GET /_search
{
"query": {
"span_within" : {
"little" : {
"span_term" : { "field1" : "foo" }
},
"big" : {
"span_near" : {
"clauses" : [
{ "span_term" : { "field1" : "bar" } },
{ "span_term" : { "field1" : "baz" } }
],
"slop" : 5,
"in_order" : true
}
}
}
}
}
big和little子句可以是任何span类型的查询。返回从小到大的匹配跨度。
专业查询(Specialized queries)
该组包含不适合其他组的查询:
-
distance_feature
query一个基于源和文档的date、date_nanos和geo_point字段之间的动态计算距离来计算分数的查询。它能够有效地跳过非竞争性命中。
-
more_like_this
query此查询查找与指定文本、文档或文档集合相似的文档。
-
percolate
query此查询查找存储为与指定文档匹配的文档的查询。
-
rank_feature
query一种基于数值特征值计算分数的查询,能够有效地跳过非竞争性命中。
-
script
query该查询允许脚本充当过滤器。另请参阅function_score查询。
-
script_score
query允许使用脚本修改子查询分数的查询。
-
wrapper
query一个以json或yaml字符串形式接受其他查询的查询。
Distance feature query(距离特征查询)
提高文档的相关性分数,使其更接近所提供的起源日期或点。例如,您可以使用此查询为接近某个日期或位置的文档赋予更大的权重。
您可以使用distance_feature查询来查找距离某个位置最近的邻居。您还可以在bool搜索的should过滤器中使用查询,为bool查询的分数添加增强的相关性分数。
创建索引
要使用distance_feature查询,您的索引必须包括date, date_nanos或geo_point字段。
要了解如何为distance_feature查询设置索引,请尝试以下示例。
1,用下面的字段映射创建一个items索引:
- name 关键词字段
- prodution_date 时间字段
- location 地理类型字段
PUT /items
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"production_date": {
"type": "date"
},
"location": {
"type": "geo_point"
}
}
}
}
将多个文档索引到此索引。
PUT /items/_doc/1?refresh
{
"name" : "chocolate",
"production_date": "2018-02-01",
"location": [-71.34, 41.12]
}
PUT /items/_doc/2?refresh
{
"name" : "chocolate",
"production_date": "2018-01-01",
"location": [-71.3, 41.15]
}
PUT /items/_doc/3?refresh
{
"name" : "chocolate",
"production_date": "2017-12-01",
"location": [-71.3, 41.12]
}
根据日期提升文档
下面的bool搜索返回name值为chocolate的文档。搜索还使用distance_feature查询来提高production_date值更接近现在的文档的相关性得分。
GET /items/_search
{
"query": {
"bool": {
"must": {
"match": {
"name": "chocolate"
}
},
"should": {
"distance_feature": {
"field": "production_date",
"pivot": "7d",
"origin": "now"
}
}
}
}
}
基于位置提升文档
下面的bool搜索返回name值为chocolate的文档。该搜索还使用distance_feature查询来提高位置值接近[-71.3,41.15]的文档的相关性得分。
GET /items/_search
{
"query": {
"bool": {
"must": {
"match": {
"name": "chocolate"
}
},
"should": {
"distance_feature": {
"field": "location",
"pivot": "1000m",
"origin": [-71.3, 41.15]
}
}
}
}
}
distance_feature核心参数:
-
field
(Required, string)用于计算距离的字段名称。该字段必须满足以下条件:
- 字段类型为date,date_nacos或者geo_point
- 索引映射参数值为true
- doc_values映射参数值为true
-
origin
(Required, string)用于计算距离的日期或起始点。
如果字段值为date或date_nanos字段,原点值必须为日期。支持Date Math,例如now-1h。
如果字段值是geo_point字段,原点值必须是一个地理点。
-
pivot
(必填项,时间单位或距离单位)距离起始点的距离,相关性分数得到一半的提升值。
当字段值为date或date_nanos字段时,pivot值必须为时间单位,如1h或10d。
如果字段值为geo_point字段,则pivot值必须为距离单位,例如1km或12m。
-
boost
(可选,浮点数)用于匹配文档的相关性得分的浮点数。该值不能为负。默认为1.0。
distance_feature查询如何计算相关性得分
distance_feature查询动态计算原始值和文档字段值之间的距离。然后,它使用这个距离作为一个特征来提高较近文档的相关性得分。
distance_feature查询计算文档的相关性分数如下所示:
relevance score = boost * pivot / (pivot + distance)
距离是原点值和文档字段值之间的绝对差值。
跳过非竞争性的命中
与function_score查询或其他更改相关性分数的方法不同,当track_total_hits参数不为true时,distance_feature查询有效地跳过非竞争性命中。
More like this query(相似查询)
More Like This查询查找与给定文档集“相似”的文档。为此,MLT选择这些输入文档的一组代表性术语,使用这些术语形成查询,执行查询并返回结果。用户控制输入文档、如何选择术语以及如何形成查询。
最简单的用例是请求与所提供的文本相似的文档。在这里,我们要求所有在其“title”和“description”字段中具有类似于“Once upon ation”的文本的电影,将所选术语的数量限制为12个。
GET /_search
{
"query": {
"more_like_this" : {
"fields" : ["title", "description"],
"like" : "Once upon a time",
"min_term_freq" : 1,
"max_query_terms" : 12
}
}
}
更复杂的用例包括将文本与索引中已经存在的文档混合。在本例中,指定文档的语法类似于Multi GET API中使用的语法。
GET /_search
{
"query": {
"more_like_this" : {
"fields" : ["title", "description"],
"like" : [
{
"_index" : "imdb",
"_id" : "1"
},
{
"_index" : "imdb",
"_id" : "2"
},
"and potentially some more text here as well"
],
"min_term_freq" : 1,
"max_query_terms" : 12
}
}
}
最后,用户可以混合一些文本,一组选定的文档,但也可以提供索引中不一定出现的文档。为了提供索引中没有的文档,语法类似于人工文档。
GET /_search
{
"query": {
"more_like_this" : {
"fields" : ["name.first", "name.last"],
"like" : [
{
"_index" : "marvel",
"doc" : {
"name": {
"first": "Ben",
"last": "Grimm"
},
"_doc": "You got no idea what I'd... what I'd give to be invisible."
}
},
{
"_index" : "marvel",
"_id" : "2"
}
],
"min_term_freq" : 1,
"max_query_terms" : 12
}
}
}
它是怎么工作的
假设我们希望找到与给定输入文档相似的所有文档。显然,输入文档本身应该与该类型的查询最匹配。根据Lucene评分公式,原因主要是由于tf-idf最高的术语。因此,具有最高tf-idf的输入文档中的术语是该文档的良好代表,并且可以在析取查询(或or)中使用以检索类似的文档。MLT查询简单地从输入文档中提取文本,对其进行分析,通常在字段中使用相同的分析器,然后进行
执行MLT的字段必须被索引,并且类型为text或关键字’。此外,当对文档使用like时,必须启用_source或存储字段或存储term_vector。为了加快分析速度,可以在索引时存储项向量。
例如,如果我们希望对“title”和“标签”执行MLT。字段,我们可以显式地在索引时存储它们的term_vector。我们仍然可以在“description”和“tags”字段上执行MLT,因为默认情况下_source是启用的,但是对这些字段的分析不会加速。
PUT /imdb
{
"mappings": {
"properties": {
"title": {
"type": "text",
"term_vector": "yes"
},
"description": {
"type": "text"
},
"tags": {
"type": "text",
"fields" : {
"raw": {
"type" : "text",
"analyzer": "keyword",
"term_vector" : "yes"
}
}
}
}
}
}
参数
唯一需要的参数是,所有其他参数都有合理的默认值。有三种类型的参数:一种用于指定文档输入,另一种用于术语选择和查询形成。
文档输入参数:
-
like
MLT查询唯一需要的参数类似并遵循通用语法,用户可以在其中指定自由格式文本和/或单个或多个文档(参见上面的示例)。指定文档的语法类似于Multi GET API使用的语法。在指定文档时,除非在每个文档请求中被重写,否则将从字段中获取文本。文本由现场的分析器进行分析,但也可以被覆盖。在字段处覆盖分析器的语法与Term Vectors API的per_field_analyzer参数的语法相似。
-
unlike
不同参数与like一起使用,以便不选择在所选文档集中找到的术语。换句话说,我们可以请求这样的文档:“Apple”,但不像:“cake crumtree”。语法和like一样。
-
fields
要从中获取和分析文本的字段列表。
术语选择参数
-
max_query_terms
将被选择的查询词的最大数目。增加这个值可以获得更高的准确性,但以牺牲查询执行速度为代价。默认值为25。
-
min_term_freq
在输入文档中,术语将被忽略的最小术语频率。默认值为2。
-
min_doc_freq
最小文档频率,低于此频率,输入文档中的术语将被忽略。默认值为5。
-
max_doc_freq
输入文档中将忽略术语的最大文档频率。这对于忽略频繁出现的单词(如停止词)很有用。默认为unbounded(0)。
-
min_word_length
术语将被忽略的最小单词长度。旧名称min_word_len已弃用。默认值为0。
-
max_world_length
词汇的最大长度,超过这个长度术语将被忽略。旧名称max_word_len已弃用。默认为unbounded(0)。
-
stop_words
一个停止词数组。这个集合中的任何单词都被认为“无趣”并被忽略。如果分析器允许使用停止词,您可能希望告诉MLT显式地忽略它们,因为出于文档相似性的目的,假设“停止词从来都不有趣”似乎是合理的。
-
analyzer
用于分词自由格式文本的分词器。默认为与字段中的第一个字段关联的分词器。
查询格式参数
-
minimum_should_match
在形成析取查询之后,此参数控制必须匹配的词的数量。语法与最小值应匹配相同。(默认为“30%”)。
-
fail_on_unsupported_field
如果指定的字段不是受支持的类型(文本或关键字),则控制查询是否失败(抛出异常)。将其设置为false以忽略该字段并继续处理。默认为true。
-
boost_terms
表单查询中的每个词都可以通过tf-idf分数进一步提高。这将设置使用此功能时使用的增强因子。默认为deactivated(0)。任何其他正值激活术语提升给定的提升因子。
-
include
指定输入文档是否也应包括在返回的搜索结果中。默认为false。
-
boost
设置整个查询的boost值。默认为1.0。
Percolate query(过滤查询)
percolate查询可用于匹配存储在索引中的查询。过滤查询本身包含文档,该文档将用作与存储的查询匹配的查询。
示例:
创建一个连个字段的索引
PUT /my-index
{
"mappings": {
"properties": {
"message": {
"type": "text"
},
"query": {
"type": "percolator"
}
}
}
}
message字段用于预处理在percolator查询中定义的文档,然后再将其编入临时索引。
查询字段用于为查询文档建立索引。它将保存一个表示实际Elasticsearch查询的json对象。查询字段已配置为使用percolator字段类型。此字段类型理解查询dsl,并以一种稍后可用于匹配在过滤查询中定义的文档的方式存储查询。
在过滤器中注册一个查询:
PUT /my-index/_doc/1?refresh
{
"query" : {
"match" : {
"message" : "bonsai tree"
}
}
}
将文档与已注册的percolator查询匹配:
GET /my-index/_search
{
"query" : {
"percolate" : {
"field" : "query",
"document" : {
"message" : "A new bonsai tree in the office"
}
}
}
}
上述要求将得到下列答复:
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.26152915,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": 0.26152915,
"_source": {
"query": {
"match": {
"message": "bonsai tree"
}
}
},
"fields" : {
"_percolator_document_slot" : [0]
}
}
]
}
}
id为1的查询与文档匹配。
_percolator_document_slot字段表示哪个文档与此查询匹配。在同时过滤多个文档时非常有用。
为了提供一个简单的示例,本文档为过滤查询和文档使用了一个索引my-index。当只注册了几个过滤查询时,这种设置可以很好地工作。但是,在使用较多的情况下,建议将查询和文档存储在单独的索引中。请参阅如何在引擎盖下工作以了解更多细节。
参数:
过滤文档时,需要设置以下参数:
-
field
percolator类型的字段,用于保存索引查询。这是必需的参数。
-
name
如果已经指定了多个过滤查询,则_percolator_document_slot字段将使用的后缀。这是可选参数。
-
document
被过滤的文件来源。
-
documents
类似于document参数,但通过json数组接受多个文档。
-
document_type
正在过滤的文档的类型/映射。此参数已弃用,将在Elasticsearch 8.0中移除。
除了指定要过滤的文档的源之外,还可以从已经存储的文档中检索源。然后,percolate查询将在内部执行get请求以获取该文档
在这种情况下,文档参数可以替换为以下参数:
-
index
文档所在的索引。这是必需的参数。
-
type
要获取的文档的类型。此参数已弃用,将在Elasticsearch 8.0中移除。
-
id
要获取的文档的id。这是必需的参数。
-
routing
可选地,使用路由来获取要过滤的文档。
-
preference
可选地,首选项用于获取要过滤的文档。
-
version
可选地,要获取的文档的预期版本。
在过滤器上下文中进行过滤
如果你对分数不感兴趣,可以通过将percolator查询包装在bool查询的filter子句或constant_score查询中来获得更好的性能:
GET /my-index/_search
{
"query" : {
"constant_score": {
"filter": {
"percolate" : {
"field" : "query",
"document" : {
"message" : "A new bonsai tree in the office"
}
}
}
}
}
}
在索引时,从percolator查询中提取项,percolator通常可以通过查看这些提取的项来确定查询是否匹配。但是,计算分数需要对每个匹配的查询进行反序列化,并针对过滤的文档运行它,这是一种成本高得多的操作。因此,如果不需要计算分数,则应该将percolate查询包装在constant_score查询或bool查询的筛选子句中。
注意,percolate查询永远不会被查询缓存缓存。
过滤多个文档
过滤查询可以同时用索引过滤查询匹配多个文档。在单个请求中过滤多个文档可以提高性能,因为查询只需要解析和匹配一次,而不是多次。
当同时过滤多个文档时,与每个匹配的过滤器查询一起返回的_percolator_document_slot字段非常重要。它指示哪些文档与特定的percolator查询匹配。这些数字与在过滤查询中指定的文档数组中的槽相关联。
GET /my-index/_search
{
"query" : {
"percolate" : {
"field" : "query",
"documents" : [
{
"message" : "bonsai tree"
},
{
"message" : "new tree"
},
{
"message" : "the office"
},
{
"message" : "office tree"
}
]
}
}
}
documents数组包含4个同时要过滤的文档。
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.7093853,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": 0.7093853,
"_source": {
"query": {
"match": {
"message": "bonsai tree"
}
}
},
"fields" : {
"_percolator_document_slot" : [0, 1, 3]
}
}
]
}
}
_percolator_document_slot表示在过滤查询中指定的第一个、第二个和最后一个文档与该查询匹配。
过滤现有文档
为了过滤新索引的文档,可以使用percolate查询。根据索引请求的响应,_id和其他元信息可用于立即过滤新添加的文档。
例如:
基于前面的例子。
索引我们想要过滤的文档:
PUT /my-index/_doc/2
{
"message" : "A new bonsai tree in the office"
}
响应:
{
"_index": "my-index",
"_type": "_doc",
"_id": "2",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"result": "created",
"_seq_no" : 1,
"_primary_term" : 1
}
过滤一个现有的文档,使用索引响应作为构建新的搜索请求的基础:
GET /my-index/_search
{
"query" : {
"percolate" : {
"field": "query",
"index" : "my-index",
"id" : "2",
"version" : 1
}
}
}
该版本是可选的,但在某些情况下很有用。我们可以确保我们正在尝试过滤刚刚建立索引的文档。在我们建立索引之后可能会进行更改,如果是这样的话,搜索请求将会失败,并出现版本冲突错误。
返回的搜索响应与前面的示例相同。
过滤查询和高亮显示
当涉及到高亮显示时,percolate查询以一种特殊的方式处理。查询命中用于突出显示过滤查询中提供的文档。而使用常规高亮显示搜索请求中的查询则用于高亮显示命中的结果。
例子
本例基于第一个示例的映射。
保存查询:
PUT /my-index/_doc/3?refresh
{
"query" : {
"match" : {
"message" : "brown fox"
}
}
}
保存另一个查询:
PUT /my-index/_doc/4?refresh
{
"query" : {
"match" : {
"message" : "lazy dog"
}
}
}
使用percolate查询和高亮显示执行一个搜索请求:
GET /my-index/_search
{
"query" : {
"percolate" : {
"field": "query",
"document" : {
"message" : "The quick brown fox jumps over the lazy dog"
}
}
},
"highlight": {
"fields": {
"message": {}
}
}
}
这将产生以下响应。
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 2,
"relation": "eq"
},
"max_score": 0.26152915,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "3",
"_score": 0.26152915,
"_source": {
"query": {
"match": {
"message": "brown fox"
}
}
},
"highlight": {
"message": [
"The quick <em>brown</em> <em>fox</em> jumps over the lazy dog"
]
},
"fields" : {
"_percolator_document_slot" : [0]
}
},
{
"_index": "my-index",
"_type": "_doc",
"_id": "4",
"_score": 0.26152915,
"_source": {
"query": {
"match": {
"message": "lazy dog"
}
}
},
"highlight": {
"message": [
"The quick brown fox jumps over the <em>lazy</em> <em>dog</em>"
]
},
"fields" : {
"_percolator_document_slot" : [0]
}
}
]
}
}
文档中突出显示了每个查询中的术语。
与搜索请求中的查询突出显示过滤器命中的结果不同,过滤器查询突出显示过滤查询中定义的文档。
当像下面的请求一样同时过滤多个文档时,突出显示的响应是不同的:
GET /my-index/_search
{
"query" : {
"percolate" : {
"field": "query",
"documents" : [
{
"message" : "bonsai tree"
},
{
"message" : "new tree"
},
{
"message" : "the office"
},
{
"message" : "office tree"
}
]
}
},
"highlight": {
"fields": {
"message": {}
}
}
}
略有不同的响应是:
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.7093853,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": 0.7093853,
"_source": {
"query": {
"match": {
"message": "bonsai tree"
}
}
},
"fields" : {
"_percolator_document_slot" : [0, 1, 3]
},
"highlight" : {
"0_message" : [
"<em>bonsai</em> <em>tree</em>"
],
"3_message" : [
"office <em>tree</em>"
],
"1_message" : [
"new <em>tree</em>"
]
}
}
]
}
}
高亮显示字段已经用它们所属的文档槽作为前缀,以便知道哪个高亮显示字段属于哪个文档。
指定多个过滤查询
可以在一个搜索请求中指定多个percolate查询:
GET /my-index/_search
{
"query" : {
"bool" : {
"should" : [
{
"percolate" : {
"field" : "query",
"document" : {
"message" : "bonsai tree"
},
"name": "query1"
}
},
{
"percolate" : {
"field" : "query",
"document" : {
"message" : "tulip flower"
},
"name": "query2"
}
}
]
}
}
}
name参数将用于标识哪个过滤器文档槽属于哪个过滤查询。
_percolator_document_slot字段名将使用_name参数中指定的内容作为后缀。如果没有指定,那么将使用字段参数,在这种情况下将导致歧义。
上面的搜索请求返回一个类似这样的响应:
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.26152915,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": 0.26152915,
"_source": {
"query": {
"match": {
"message": "bonsai tree"
}
}
},
"fields" : {
"_percolator_document_slot_query1" : [0]
}
}
]
}
}
_percolator_document_slot_query1 percolator slot字段表示这些匹配的槽位来自过滤查询,其中_name参数设置为query1。
它是如何在引擎盖下工作的
当将文档索引到配置了percolator字段类型映射的索引中时,文档的查询部分将被解析为Lucene查询并存储到Lucene索引中。存储了查询的二进制表示,还分析了查询的术语并将其存储到索引字段中。
在搜索时,请求中指定的文档被解析为Lucene文档,并存储在内存中的临时Lucene索引中。这个内存索引只能保存这个文档,并且它为此进行了优化。在此之后,将基于内存索引中的术语构建一个特殊查询,该索引根据已索引的查询术语选择候选percolator查询。然后,如果这些查询确实匹配,则由内存中的索引对它们进行计算。
在过滤查询执行期间,选择候选过滤查询匹配是一项重要的性能优化,因为它可以显著减少内存索引需要评估的候选匹配的数量。percolator查询可以这样做的原因是,在为percolator查询建立索引期间,查询词会被提取出来并使用percolator查询建立索引。不幸的是,过滤器不能从所有查询中提取术语(例如通配符或geo_shape查询),因此在某些情况下,过滤器不能进行选择
GET /_search
{
"query": {
"term" : {
"query.extraction_result" : "failed"
}
}
}
上面的示例假设映射中有一个类型为percolator的查询字段。
考虑到过滤的设计,为过滤查询和被过滤的文档使用单独的索引通常是有意义的,而不是像我们在示例中所做的那样使用单个索引。这种方法有几个好处:
- 因为过滤查询包含与过滤文档不同的一组字段,所以使用两个单独的索引可以以更密集、更有效的方式存储字段。
- 过滤查询的伸缩方式与其他查询不同,因此使用不同的索引配置(如主分片的数量)可以提高渗透性能。
Rank feature query(排序特征查询)
根据rank_feature或rank_features字段的数值提高文档的相关性得分。
rank_feature查询通常用于bool查询的should子句中,这样它的相关性分数就会被添加到bool查询的其他分数中。
与function_score查询或其他更改相关性分数的方法不同,当track_total_hits参数不为真时,rank_feature查询有效地跳过非竞争性命中。这可以极大地提高查询速度。
排序特征函数
为了根据rank特征字段计算相关性分数,rank_feature查询支持以下数学函数:
- Saturation
- Logatithm
- Sigmoid
如果您不知道从哪里开始,我们建议使用Saturation函数。如果没有提供函数,rank_feature查询默认使用saturation函数。
创建索引
要使用rank_feature查询,索引必须包含rank_feature或rank_features字段映射。要了解如何为rank_feature查询设置索引,请尝试以下示例。
用以下字段映射创建一个测试索引:
- pagerank rank_feature字段,用于衡量网站的重要性
- url_length rank_feature字段,包含网站URL的长度。对于本例,长URL与相关性呈负相关,由positive_score_impact值false表示。
- topics rank_features字段,包含主题列表和每个文档与该主题的连接程度的度量
PUT /test
{
"mappings": {
"properties": {
"pagerank": {
"type": "rank_feature"
},
"url_length": {
"type": "rank_feature",
"positive_score_impact": false
},
"topics": {
"type": "rank_features"
}
}
}
}
将几个文档索引到测试索引中。
PUT /test/_doc/1?refresh
{
"url": "http://en.wikipedia.org/wiki/2016_Summer_Olympics",
"content": "Rio 2016",
"pagerank": 50.3,
"url_length": 42,
"topics": {
"sports": 50,
"brazil": 30
}
}
PUT /test/_doc/2?refresh
{
"url": "http://en.wikipedia.org/wiki/2016_Brazilian_Grand_Prix",
"content": "Formula One motor race held on 13 November 2016",
"pagerank": 50.3,
"url_length": 47,
"topics": {
"sports": 35,
"formula one": 65,
"brazil": 20
}
}
PUT /test/_doc/3?refresh
{
"url": "http://en.wikipedia.org/wiki/Deadpool_(film)",
"content": "Deadpool is a 2016 American superhero film",
"pagerank": 50.3,
"url_length": 37,
"topics": {
"movies": 60,
"super hero": 65
}
}
示例查询
下面的查询搜索2016年,并提高基于pagerank、url_length和体育运动的相关性得分。
GET /test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"content": "2016"
}
}
],
"should": [
{
"rank_feature": {
"field": "pagerank"
}
},
{
"rank_feature": {
"field": "url_length",
"boost": 0.1
}
},
{
"rank_feature": {
"field": "topics.sports",
"boost": 0.4
}
}
]
}
}
}
rank_feature核心参数:
-
field
(Required, string)用于提高相关性分数的rank_feature或rank_features字段。
-
boost
(可选,浮点数)用于降低或增加相关性评分的浮点数。默认为1.0。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
-
saturation
(可选,函数对象)饱和度函数用于提高基于秩特征字段值的相关性得分。如果没有提供函数,rank_feature查询默认使用saturation函数。更多信息请参见饱和度。
只能提供一个saturation、log或sigmoid。
-
log
(可选,函数对象)对数函数用于基于rank特征字段的值提高相关性得分。有关更多信息,请参阅对数。
只能提供一个saturation、log或sigmoid。
-
sigmod
(可选,函数对象)用于根据rank特征字段的值提高相关性得分的Sigmoid函数。有关更多信息,请参阅Sigmoid。
只能提供一个saturation、log或sigmoid
Saturation
饱和函数给出的分数等于S / (S + pivot),其中S是秩特征字段的值,pivot是一个可配置的pivot值,因此如果S小于pivot,结果将小于0.5,否则大于0.5。分数总是(0,1)。
如果排名特征具有负的得分影响,则函数将计算为pivot / (S + pivot),当S增加时,pivot会减少。
GET /test/_search
{
"query": {
"rank_feature": {
"field": "pagerank",
"saturation": {
"pivot": 8
}
}
}
}
如果没有提供枢轴值,Elasticsearch将计算一个默认值,该值等于索引中所有rank特征值的近似几何平均值。如果您没有机会训练一个好的枢轴值,我们建议使用这个默认值。
GET /test/_search
{
"query": {
"rank_feature": {
"field": "pagerank",
"saturation": {}
}
}
}
Logarithm
log函数给出了一个等于log(scaling_factor + S)的分数,其中S是rank特征字段的值,scaling_factor是一个可配置的缩放因子。分数是无限的。
这个函数只支持对分数有积极影响的排名特征。
GET /test/_search
{
"query": {
"rank_feature": {
"field": "pagerank",
"log": {
"scaling_factor": 4
}
}
}
}
Sigmoid
sigmoid函数是饱和函数的一个扩展,它增加了一个可配置的指数。分数计算为Sexp / (Sexp + pivotexp)。与饱和函数一样,pivot是给出0.5分数的S值,分数为(0,1)。
指数必须是正的,通常在[0.5,1]。一个好的数值应该通过训练计算出来。如果您没有机会这样做,我们建议您使用饱和函数代替。
GET /test/_search
{
"query": {
"rank_feature": {
"field": "pagerank",
"sigmoid": {
"pivot": 7,
"exponent": 0.6
}
}
}
}
Script query(脚本查询)
根据提供的脚本筛选文档。脚本查询通常用于筛选器上下文中。
例如:
GET /_search
{
"query": {
"bool" : {
"filter" : {
"script" : {
"script" : {
"source": "doc['num1'].value > 1",
"lang": "painless"
}
}
}
}
}
}
脚本查询核心参数:
-
script
(必选,脚本对象)包含作为查询运行的脚本。这个脚本必须返回一个布尔值,true或false。
自定义参数
与过滤器一样,脚本也被缓存以便更快地执行。如果你经常更改脚本的参数,我们建议你将它们存储在脚本的params参数中。例如:
GET /_search
{
"query": {
"bool" : {
"filter" : {
"script" : {
"script" : {
"source" : "doc['num1'].value > params.param1",
"lang" : "painless",
"params" : {
"param1" : 5
}
}
}
}
}
}
}
Script score query(脚本评分查询)
使用脚本为返回的文档提供自定义评分。
例如,如果评分函数很昂贵,而您只需要计算一组经过过滤的文档的分数,那么script_score查询就很有用。
下面的script_score查询为每个返回的文档分配一个分数,等于likes字段值除以10。
GET /_search
{
"query" : {
"script_score" : {
"query" : {
"match": { "message": "elasticsearch" }
},
"script" : {
"source" : "doc['likes'].value / 10 "
}
}
}
}
script_score核心参数:
-
query
(必选,查询对象)返回文档的查询。
-
script
(必选,脚本对象)用于计算查询返回的文档分数的脚本。
script_score查询的最终相关性得分不能为负。为了支持某些搜索优化,Lucene要求分数为正或0。
-
min_score
(可选,浮点数)相关性得分低于此浮点数的文档将被排除在搜索结果之外。
在脚本中使用相关性评分
在脚本中,您可以访问_score变量,该变量表示文档的当前相关性得分。
预定义函数
您可以在脚本中使用任何可用的无痛函数。您还可以使用以下预定义函数自定义评分:
- saturation
- sigmoid
- random score function
- Decay functions for numeric fields
- Decay functions for geo fields
- Decay functions for date fields
我们建议使用这些预定义的函数,而不是自己编写函数。这些函数利用了Elasticsearch内部机制的效率。
Saturation
saturation(value,k) = value/(k + value)
"script" : {
"source" : "saturation(doc['likes'].value, 1)"
}
Sigmoid
sigmoid(value, k, a) = value^a/ (k^a + value^a)
"script" : {
"source" : "sigmoid(doc['likes'].value, 2, 1)"
}
向量场的函数
此功能处于技术预览阶段,在未来的版本中可能会更改或删除。Elastic将尽最大努力修复任何问题,但技术预览中的功能不受官方GA功能的支持SLA的约束。
这些函数用于dense_vector和sparse_vector字段。
在向量函数的计算过程中,对所有匹配的文档进行线性扫描。因此,可以预期查询时间会随着匹配文档的数量线性增长。出于这个原因,我们建议使用查询参数限制匹配文档的数量。
对于dense_vector字段,cosessimilarity计算给定查询向量和文档向量之间的余弦相似度的度量。
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "cosineSimilarity(params.queryVector, doc['my_dense_vector'])",
"params": {
"queryVector": [4, 3.4, -0.2]
}
}
}
}
}
为了利用脚本优化,提供一个查询向量作为脚本参数。
类似地,对于sparse_vector字段,cosineSimilaritySparse计算给定查询向量和文档向量之间的余弦相似度。
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "cosineSimilaritySparse(params.queryVector, doc['my_sparse_vector'])",
"params": {
"queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
}
}
}
}
}
对于dense_vector字段,dotProduct计算给定查询向量和文档向量之间点积的度量。
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "dotProduct(params.queryVector, doc['my_dense_vector'])",
"params": {
"queryVector": [4, 3.4, -0.2]
}
}
}
}
}
类似地,对于sparse_vector字段,dotProductSparse计算给定查询向量和文档向量之间的点积。
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "dotProductSparse(params.queryVector, doc['my_sparse_vector'])",
"params": {
"queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
}
}
}
}
}
如果文档中没有执行vector函数的vector字段的值,则此文档的结果将返回0。
如果文档的密集向量字段的维数与查询的向量不同,则会抛出错误。
Random score function
Random_score函数生成从0到不包括1的均匀分布的分数。
randomScore函数的语法如下:randomScore(, )。它有一个必需的参数seed作为整型值,一个可选参数fieldName作为字符串值。
"script" : {
"source" : "randomScore(100, '_seq_no')"
}
如果fieldName参数被省略,内部Lucene文档id将被用作随机的来源。这是非常有效的,但不幸的是不可复制的,因为文档可能会通过合并重新编号。
"script" : {
"source" : "randomScore(100)"
}
请注意,在同一个shard内且具有相同字段值的文档将获得相同的分数,因此通常希望使用一个对于整个shard的所有文档具有唯一值的字段。一个很好的默认选择可能是使用_seq_no字段,它的唯一缺点是,如果文档更新,分数将会改变,因为更新操作也会更新_seq_no字段的值。
Wrapper query(包装查询)
一个接受任何其他查询作为base64编码字符串的查询。
GET /_search
{
"query" : {
"wrapper": {
"query" : "eyJ0ZXJtIiA6IHsgInVzZXIiIDogIktpbWNoeSIgfX0="
}
}
}
Base64编码字符串:{“term”: {" user": “Kimchy”}}
该查询在Java高级REST客户端或传输客户端上下文中更有用,可以将查询作为json格式的字符串接受。在这些情况下,查询可以指定为json或yaml格式的字符串,也可以指定为查询构建器(在Java高级REST客户端中可用)。
Term-Level query(术语级查询)
可以使用术语级查询根据结构化数据中的精确值查找文档。结构化数据的例子包括日期范围、IP地址、价格或产品id。
与全文查询不同,术语级查询不分词搜索词。相反,术语级查询匹配存储在字段中的确切术语。
术语级查询仍然使用normalizer属性对关键字字段的搜索词进行规范化。有关更多详细信息,请参见normalizer。
term-level query包含:
-
exists
query返回包含某个字段的任何索引值的文档。
-
fuzzy
query返回包含与搜索词相似的词的文档。Elasticsearch使用Levenshtein编辑距离来测量相似性或模糊性
-
ids
query根据文档id返回文档。
-
range
query返回包含给定范围内术语的文档。
-
regexp
query返回包含正则表达式匹配项的文档。
-
term
query返回在所提供的字段中包含确切术语的文档。
-
terms
query返回在所提供的字段中包含一个或多个确切术语的文档。
-
terms_set
query返回在所提供的字段中包含最少数量的确切术语的文档。可以使用字段或脚本定义匹配项的最小数目。
-
type
query返回指定类型的文档。
-
wildcard
query返回包含与通配符模式匹配的术语的文档
Exists query
返回包含字段索引值的文档。
由于各种原因,文档字段可能不存在索引值:
- 源JSON中的字段为null或[]
- 字段在映射中设置了“index”:false
- 字段值的长度超过了映射中的ignore_above设置
- 字段值是畸形的,并且在映射中定义了ignore_malformed
GET /_search
{
"query": {
"exists": {
"field": "user"
}
}
}
exists核心参数:
-
field
(Required, string)要搜索的字段名称。
如果JSON值为null或[],则认为字段不存在,这些值将表明该字段确实存在:
- 空字符串,如"“或”-"
- 包含null和另一个值的数组,例如[null, “foo”]
- 在字段映射中定义的自定义空值
查找缺少索引值的文档
要查找缺少字段索引值的文档,可以使用must_not布尔查询和exists查询。
下面的搜索返回缺少用户字段索引值的文档。
GET /_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "user"
}
}
}
}
}
Fuzzy query(模糊查询)
返回包含与搜索词相似的词的文档(由Levenshtein编辑距离衡量)。
编辑距离是将一个术语转换为另一个术语所需的单个字符更改的次数。这些变化包括:
- 改变字符(box->fox)
- 移除字符(black->lack)
- 插入字符(sic->sicK)
- 调换两个相邻的字符(act->cat)
为了找到相似的词,模糊查询在指定的编辑距离内创建搜索词的所有可能变体或扩展集。查询然后返回每个展开的精确匹配。
GET /_search
{
"query": {
"fuzzy": {
"user": {
"value": "ki"
}
}
}
}
使用高级参数的示例
GET /_search
{
"query": {
"fuzzy": {
"user": {
"value": "ki",
"fuzziness": "AUTO",
"max_expansions": 50,
"prefix_length": 0,
"transpositions": true,
"rewrite": "constant_score"
}
}
}
}
fuzzy核心参数:
-
(必选,对象)要搜索的字段。
核心参数:
-
value
(Required, string)您希望在提供的中找到的术语。
-
fuzziness
(可选,字符串)允许匹配的最大编辑距离。有关有效值和更多信息,请参阅模糊性。
-
max_expansions
(可选,整数)创建的最大变量个数。默认值为50。
避免在max_expansions参数中使用较大的值,特别是当prefix_length参数值为0时。max_expansions参数中的高值可能会导致性能较差,因为检查的变量数量太多。
-
prefix_length
(可选,整数)创建扩展时,保留起始字符的个数。默认值为0。
-
transpositions
(可选,boolean)表示编辑是否包括两个相邻字符的转置(ab→ba)。默认为true。
-
rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅rewrite参数。
IDS query
根据文档的id返回文档。这个查询使用存储在_id字段中的文档id。
GET /_search
{
"query": {
"ids" : {
"values" : ["1", "4", "100"]
}
}
}
核心参数:
-
values
(Required, array of strings)文档id数组
prefix query(前缀查询)
返回在提供的字段中包含特定前缀的文档。
下面的搜索将返回用户字段包含以ki开头的术语的文档。
GET /_search
{
"query": {
"prefix": {
"user": {
"value": "ki"
}
}
}
}
核心参数:
-
(必选,对象)要搜索的字段。
核心参数:
-
value
(必选,字符串)您希望在提供的中找到的术语的开头字符。
-
rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅rewrite参数。
简短请求示例
可以通过组合和value参数来简化前缀查询语法。例如:
GET /_search
{
"query": {
"prefix" : { "user" : "ki" }
}
}
加快前缀查询
可以使用index_prefixes映射参数加速前缀查询。如果启用,Elasticsearch将在一个单独的字段中索引2到5个字符之间的前缀。这使得Elasticsearch以更大的索引为代价更有效地运行前缀查询。
Range query(范围查询)
返回包含给定范围内术语的文档。
下面的搜索将返回年龄字段包含10到20之间的术语的文档。
GET _search
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}
range查询核心参数:
-
必选,对象)要搜索的字段。
核心参数:
-
gt
大于
-
gte
大于等于
-
lt
小于
-
lte
小于等于
-
format
(可选,字符串)用于转换查询中的日期值的日期格式。
默认情况下,Elasticsearch使用的映射中提供的日期格式。该值覆盖映射格式
有关有效语法,请参阅format。
如果格式和日期值不完整,Elasticsearch会将任何缺失的年、月或日期组件替换为Unix时间的开始,即1970年1月1日。
例如,如果格式值为dd, Elasticsearch将gte值10转换为1970-01-10T00:00:00.000Z。
-
relation
(可选,string)指定范围查询如何匹配范围字段的值。有效值为:
-
INTERSECTS(默认)
匹配与查询范围相交的范围字段值的文档。
-
CONTAINS
匹配具有完全包含查询范围的范围字段值的文档。
-
WITHIN
完全在查询范围内匹配具有范围字段值的文档。
-
-
time_zone
(可选,字符串)UTC (Coordinated Universal Time)偏移量或IANA时区,用于将查询中的日期值转换为UTC。
有效值为ISO 8601 UTC偏移量,如+01:00或-08:00,IANA时区id,如America/Los_Angeles。
有关使用time_zone参数的示例查询,请参见范围查询中的Time zone。
time_zone参数不影响now的日期数学值。now始终是当前系统时间(UTC)。
但是,time_zone参数转换使用now和日期数学舍入计算的日期。例如,time_zone参数将转换为now/d的值
-
boost
(可选,float)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
可以使用boost参数调整包含两个或多个查询的搜索的相关性得分。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
使用带日期字段的范围查询
当参数是一个日期字段数据类型时,您可以使用date math和以下参数:
gt gte lt lte
例如,下面的搜索返回的文档中,时间戳字段包含今天和昨天之间的日期。
GET _search
{
"query": {
"range" : {
"timestamp" : {
"gte" : "now-1d/d",
"lt" : "now/d"
}
}
}
}
日期数学和舍入
Elasticsearch将参数中的数学值四舍五入如下:
-
gt
四舍五入到最近的毫秒。
例如,2014-11-18||/M四舍五入为2014-11-30T23:59:59.999,不包括整个月。
-
gte
四舍五入到第一毫秒。
例如,2014-11-18||/M四舍五入到2014-11-01,包括整个月。
-
lt
四舍五入到第一毫秒。
例如,2014-11-18||/M四舍五入到2014-11-01,不包括整个月。
-
lte
四舍五入到最近的毫秒。
例如,2014-11-18||/M四舍五入为2014-11-30T23:59:59.999,不包括整个月。
使用实例使用time_zone参数查询
您可以使用time_zone参数使用UTC偏移量将日期值转换为UTC。例如:
GET _search
{
"query": {
"range" : {
"timestamp" : {
"time_zone": "+01:00",
"gte": "2015-01-01 00:00:00",
"lte": "now"
}
}
}
}
- 指示日期值使用UTC +01:00偏移量。
- 如果UTC偏移量为+01:00,Elasticsearch将此日期转换为2014-12-31T23:00:00 UTC。
- time_zone参数不影响now值。
Regexp query(正则查询)
返回包含正则表达式匹配项的文档。
正则表达式是一种使用占位符(称为操作符)来匹配数据中的模式的方法。有关regexp查询支持的操作符列表,请参见正则表达式语法。
下面的搜索将返回用户字段包含以k开头、以y结尾的任何术语的文档。*操作符匹配任何长度的任何字符,不包括任何字符。匹配的术语包括ky, kay和kimchy。
GET /_search
{
"query": {
"regexp": {
"user": {
"value": "k.*y",
"flags" : "ALL",
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}
regexp核心参数:
-
(必选,对象)要搜索的字段。
核心参数:
-
value
(Required, string)正则表达式的术语,您希望在提供的<字段>。有关受支持的操作符列表,请参见正则表达式语法。
默认情况下,正则表达式不超过1000个字符。您可以更改此限制使用index.max_regex_length设置。
regexp查询的性能可以根据所提供的正则表达式而变化。为了提高性能,请避免使用通配符模式,例如。或。?+,不带前缀或后缀。
-
flags
(可选,string)为正则表达式启用可选操作符。有关有效值和更多信息,请参见正则表达式语法。
-
max_determinized_states
(可选,整数)查询所需的最大自动机状态数。默认是10000。
Elasticsearch在内部使用Apache Lucene解析正则表达式。Lucene将每个正则表达式转换为包含许多确定状态的有限自动机。
您可以使用此参数来防止转换无意中消耗太多资源。要运行复杂的正则表达式,可能需要增加这个限制。
-
rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅rewrite参数。
Term query(术语查询)
返回在所提供的字段中包含确切术语的文档。
您可以使用术语查询根据精确的值(如价格、产品ID或用户名)查找文档。
避免对文本字段使用术语查询。
默认情况下,Elasticsearch更改文本字段的值作为分词的一部分。这可能会使查找文本字段值的精确匹配变得困难。
要搜索文本字段值,请使用匹配查询。
GET /_search
{
"query": {
"term": {
"user": {
"value": "Kimchy",
"boost": 1.0
}
}
}
}
term核心参数:
-
(必选,对象)要搜索的字段。
核心参数:
-
value
(Required, string)您希望在提供的中找到的术语。要返回文档,术语必须完全匹配字段值,包括空格和大写。
-
boost
(可选,float)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
可以使用boost参数调整包含两个或多个查询的搜索的相关性得分。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
避免对文本字段使用术语查询
默认情况下,Elasticsearch会在分词过程中更改文本字段的值。例如,默认的标准分词器修改文本字段值如下:
- 删除大部分标点符号
- 将剩余的内容分成单独的单词,称为标记
- 将标记全部小写
为了更好地搜索文本字段,match查询还会在执行搜索之前分析您提供的搜索词。这意味着匹配查询可以在文本字段中搜索已分词的标记,而不是精确的术语。
术语查询不分词搜索词。术语查询只搜索您提供的确切术语。这意味着在搜索文本字段时,术语查询可能返回较差的结果或不返回结果。
要查看搜索结果的差异,请尝试以下示例。
1,使用名为full_text的文本字段创建索引。
PUT my_index
{
"mappings" : {
"properties" : {
"full_text" : { "type" : "text" }
}
}
}
2,索引一个值为Quick Brown Foxes的文档在full_text字段中。
PUT my_index/_doc/1
{
"full_text": "Quick Brown Foxes!"
}
因为full_text是一个文本字段,Elasticsearch更改Quick Brown Foxes分词为[quick brown fox]
3,使用术语查询搜索Quick brown foxes在full_text字段中。包含pretty参数,这样响应的可读性更强。
GET my_index/_search?pretty
{
"query": {
"term": {
"full_text": "Quick Brown Foxes!"
}
}
}
因为full_text字段不再包含准确的术语Quick Brown
foxes,则术语查询搜索不会返回任何结果。
4,使用match查询搜索Quick brown foxes在full_text字段中。
GET my_index/_search?pretty
{
"query": {
"match": {
"full_text": "Quick Brown Foxes!"
}
}
}
与术语查询不同,匹配查询分词您提供的搜索词,Quick Brown Foxes!,然后执行搜索。然后match查询返回full_text字段中包含quick、brown或fox标记的任何文档。
下面是结果中包含索引文档的匹配查询搜索的响应。
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.8630463,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.8630463,
"_source" : {
"full_text" : "Quick Brown Foxes!"
}
}
]
}
}
Terms query
返回在所提供的字段中包含一个或多个确切术语的文档。
terms查询与term查询相同,只是可以搜索多个值。
下面的搜索返回用户字段包含kimchy或elasticsearch的文档。
GET /_search
{
"query" : {
"terms" : {
"user" : ["kimchy", "elasticsearch"],
"boost" : 1.0
}
}
}
terms核心参数:
-
(可选,对象)要搜索的字段。
此参数的值是您希望在提供的字段中找到的术语数组。要返回文档,一个或多个术语必须精确匹配字段值,包括空格和大写。
默认情况下,Elasticsearch将术语查询限制为最多65,536个术语。您可以使用index.max_terms_count更改此限制。
若要使用现有文档的字段值作为搜索术语,请使用Terms lookUp。
-
boost
(可选,float)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
可以使用boost参数调整包含两个或多个查询的搜索的相关性得分。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
高亮terms查询
Elasticsearch可能不会为terms查询返回突出显示结果,这取决于:
- 高亮类型
- 查询中的术语数
Terms Lookup
术语查找获取现有文档的字段值。Elasticsearch然后使用这些值作为搜索条件。这在搜索大量术语时很有帮助。
因为术语查找是从文档中获取值,所以必须启用_source映射字段才能使用术语查找。默认情况下,_source字段是启用的。
默认情况下,Elasticsearch将术语查询限制为最多65,536个术语。这包括使用术语查找获取的术语。您可以使用index.max_terms_count设置。
要执行术语查找,请使用以下参数。
terms lookup参数:
-
index
(可选,string)获取字段值的索引名。
-
id
(可选,string)从其中获取字段值的文档ID。
-
path
(可选,string)获取字段值的字段名。Elasticsearch使用这些值作为查询的搜索词。
如果字段值包含嵌套的内部对象数组,则可以使用点符号语法访问这些对象。
-
routing
(可选,字符串)文档的自定义路由值,从中获取术语值。如果在索引文档时提供了自定义路由值,则此参数是必需的。
要了解术语查找的工作原理,请尝试以下示例。
1,使用名为color的关键字字段创建索引。
PUT my_index
{
"mappings" : {
"properties" : {
"color" : { "type" : "keyword" }
}
}
}
2, 在颜色字段中索引ID为1且值为[“blue”, “green”]的文档。
PUT my_index/_doc/1
{
"color": ["blue", "green"]
}
3,在颜色字段中索引ID为2且值为蓝色的另一个文档。
PUT my_index/_doc/2
{
"color": "blue"
}
4,使用terms查找参数的术语查询来查找包含一个或多个与文档2相同的术语的文档。包含pretty参数,这样响应的可读性更强。
GET my_index/_search?pretty
{
"query": {
"terms": {
"color" : {
"index" : "my_index",
"id" : "2",
"path" : "color"
}
}
}
}
因为文档2和文档1在颜色字段中都包含蓝色值,Elasticsearch返回两个文档。
{
"took" : 17,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"color" : [
"blue",
"green"
]
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"color" : "blue"
}
}
]
}
}
Term set query
返回在所提供的字段中包含最少数量的确切术语的文档。
terms_set查询与terms查询相同,只是您可以定义返回文档所需的匹配术语的数量。例如:
- programming_languages字段包含已知编程语言的列表,例如针对求职者的c++、java或php。可以使用terms_set查询返回至少匹配其中两种语言的文档。
- permissions字段包含应用程序可能的用户权限列表。可以使用terms_set查询返回与这些权限子集匹配的文档。
创建索引
在大多数情况下,为了使用terms_set查询,需要在索引中包含数字字段映射。此数字字段包含返回文档所需的匹配项的数量。
要了解如何为terms_set查询设置索引,请尝试以下示例。
1,用以下字段映射创建一个索引job-candidate:
- name 类型为keyword,该字段包含求职者的姓名
- programming_languages,keyword类型,该字段包含应聘者知道的编程语言。
- required_matches,numeric long类型 此字段包含返回文档所需的匹配项的数量。
PUT /job-candidates
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"programming_languages": {
"type": "keyword"
},
"required_matches": {
"type": "long"
}
}
}
}
2,索引ID为1和以下值的文档:
PUT /job-candidates/_doc/1?refresh
{
"name": "Jane Smith",
"programming_languages": ["c++", "java"],
"required_matches": 2
}
3,索引ID为2和以下值的另一个文档:
PUT /job-candidates/_doc/2?refresh
{
"name": "Jason Response",
"programming_languages": ["java", "php"],
"required_matches": 2
}
现在可以使用required_matches字段值作为在terms_set查询中返回文档所需的匹配术语的数量。
示例查询:
下面的搜索返回的文档中,programming_languages字段至少包含以下两个术语:
c++ java php
minimum_should_match_field是required_matches。这意味着所需的匹配项的数量是2,即required_matches字段的值。
GET /job-candidates/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": ["c++", "java", "php"],
"minimum_should_match_field": "required_matches"
}
}
}
}
terms_set核心参数:
-
(必选,对象)要搜索的字段。
参数
-
terms
(Required, array of strings)您希望在提供的中找到的术语数组。要返回文档,必须有一定数量的术语与字段值完全匹配,包括空格和大写。
所需的匹配项数量在minimum_should_match_field或minimum_should_match_script参数中定义。
-
minimum_should_match_field
(可选,string)数字字段,包含返回文档所需的匹配术语的数量。
-
minimum_should_match_script
(可选,字符串)自定义脚本,包含返回文档所需的匹配术语的数量。
有关参数和有效值,请参阅脚本。
有关使用minimum_should_match_script参数的示例查询,请参见如何使用minimum_should_match_script参数。
如何使用minimum_should_match_script参数
您可以使用minimum_should_match_script使用脚本定义所需的匹配术语数量。如果需要动态设置所需术语的数量,这很有用。
下面的搜索返回的文档中,programming_languages字段至少包含以下两个术语:
c++ Java PHP
该查询的source参数表示:
- 需要匹配的术语数量不能超过params.num.terms, terms字段中提供的术语数量。
- 需要匹配的术语数量是2,即required_matches字段的值。
GET /job-candidates/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": ["c++", "java", "php"],
"minimum_should_match_script": {
"source": "Math.min(params.num_terms, doc['required_matches'].value)"
},
"boost": 1.0
}
}
}
}
Type query(类型查询)
7.0.0中已弃用。
类型和类型查询已弃用,并且正在被删除。
Wildcard query(通配符查询)
返回包含与通配符模式匹配的术语的文档。
通配符是匹配一个或多个字符的占位符。例如,*通配符匹配零个或多个字符。您可以将通配符与其他字符组合起来创建通配符模式。
下面的搜索将返回用户字段包含以ki开头、以y结尾的词的文档。这些匹配的词可以包括kiy、kity或kimchy。
GET /_search
{
"query": {
"wildcard": {
"user": {
"value": "ki*y",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
wildcard核心参数:
-
要搜索的字段
核心参数:
-
value
(Required, string)您希望在提供的中找到的术语的通配符模式。
该参数支持两个通配符:
?
:匹配任何单个字符*
: 是否可以匹配零个或多个字符,包括一个空字符
避免使用*或?开头模式。这可能会增加查找匹配项所需的迭代次数,并降低搜索性能。
-
boost
(可选,float)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
可以使用boost参数调整包含两个或多个查询的搜索的相关性得分。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
-
rewrite
(可选,字符串)用于重写查询的方法。获取有效值和更多信息
minimum_should_match 参数
minimum_should_match参数可能的值:
-
整数
指示一个固定的值,不管可选子句的数量。
如:3
-
负整数
指示可选子句的总数,减去此数应为必填项。
如:-2
-
百分比
指示必需的可选子句总数的这个百分比。从百分比计算出的数字四舍五入后用作最小值。
如:75%
-
负百分比
指示可选子句总数中可以减少的百分比。从百分比计算出的数字是四舍五入,然后从总数中减去以确定最小值。
如:-25%
-
组合
正整数,后面跟着小于号,后面跟着前面提到的任何说明符是一个条件说明。它表示如果可选子句的数量等于(或小于)整数,则它们都是必需的,但如果大于整数,则适用该规范。在这个例子中,如果有1到3个从句,它们都是必需的,但对于4个或4个以上的从句,只有90%是必需的。
如:3<90%
-
多值组合
多个条件规范可以用空格分隔,每个条件规范只对比它前面的数字大的数字有效。在这个例子中:如果有1个或2个条款,两个都是必须的,如果有3-9个条款,除了25%以外都是必须的,如果有9个以上条款,除了3个以外都是必须的。
如:2<-25% 9<-3
在处理百分比时,可以使用负值来获得边缘情况下的不同行为。当处理4个从句时,75%和-25%的意思是一样的,但当处理5个从句时,75%意味着需要3个,而-25%意味着需要4个。
如果基于规范的计算确定不需要可选子句,则在搜索时仍然适用关于布尔查询的通常规则(不包含必选子句的布尔查询仍然必须匹配至少一个可选子句)
无论计算结果是多少,大于可选子句数量的值或小于1的值将永远不会被使用。(即:无论计算结果的结果多低或多高,所需匹配的最小数目永远不会小于1或大于子句的数目。
rewrite 参数
此参数仅供专业用户使用。更改此参数的值可能会影响搜索性能和相关性。
Elasticsearch在内部使用Apache Lucene来增强索引和搜索。在它们的原始形式中,Lucene不能执行以下查询:
- fuzzy
- prefix
- query_string
- regexp
- wildcard
为了执行它们,Lucene将这些查询更改为更简单的形式,例如bool查询或位集。
rewrite决定:
- Lucene如何计算每个匹配文档的相关性分数
- Lucene是否将原始查询更改为bool查询或位集
- 如果更改为bool查询,则包含哪些术语查询子句
有效值
-
constant_score
(默认)使用constant_score_boolean方法减少匹配项。否则,该方法将按顺序查找所有匹配的项,并使用位集返回匹配的文档。
-
constant_score_boolean
为每个文档分配一个等于boost参数的相关性分数。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
此方法会导致最终的bool查询超过indices.query.bool.max_clause_count中的子句限制。如果查询超过这个限制,Elasticsearch将返回一个错误。
-
scoring_boolean
计算每个匹配文档的相关性得分。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
此方法会导致最终的bool查询超过indices.query.bool.max_clause_count中的子句限制。如果查询超过这个限制,Elasticsearch将返回一个错误。
-
top_terms_blended_freq_N
计算每个匹配文档的相关性得分,就好像所有术语都有相同的频率一样。这个频率是所有匹配项的最大频率。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包括对得分最高的N个术语的查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
-
top_terms_boost_N
为每个匹配的文档分配一个等于boost参数的相关性分数。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包含前N个术语的术语查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
-
top_terms_N
计算每个匹配文档的相关性得分。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包括对得分最高的N个术语的查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
rewrite参数的性能考虑因素
对于大多数用途,我们建议使用constant_score、constant_score_boolean或top_terms_boost_N重写方法。
其他方法计算相关性得分。这些分数计算通常是昂贵的,并且不会改善查询结果。
regular expression synatax(正则表达式)
正则表达式是一种使用占位符(称为操作符)来匹配数据中的模式的方法。
Elasticsearch在以下查询中支持正则表达式:
regexp
query_string
Elasticsearch使用Apache Lucene的正则表达式引擎来解析这些查询。
保留字符
Lucene的正则表达式引擎支持所有Unicode字符。但是,以下字符保留为操作符:
. ? + * | { } [ ] ( ) " \
根据启用的可选操作符,以下字符也可能被保留:
# @ & < > ~
要从字面上使用这些字符之一,请使用前面的反斜杠转义或用双引号将其括起来。例如:
\@
呈现为文字“@”
\\
呈现为文字“\”
"john@smith.com"
呈现为'john@smith.com'
标准运算符
Lucene的正则表达式引擎不使用Perl Compatible regular Expressions (PCRE)库,但它支持以下标准操作符。
-
.
匹配任意字符。例如:
ab. # 匹配'aba', 'abb', 'abz', etc.
-
?
重复上述字符0次或1次。通常用于使前面的字符是可选的。例如:
abc? # 匹配 'ab' and 'abc'
-
+
重复前面的字符一次或多次。例如:
ab+ # 匹配'abb', 'abbb', 'abbbb', etc.
-
*
重复上述字符0次或多次。例如:
ab* # 匹配 'ab', 'abb', 'abbb', 'abbbb', etc.
-
{}
前一个字符可以重复的最小和最大次数。例如:
a{2} # 匹配 'aa'
a{2,4} # 匹配 'aa', 'aaa', and 'aaaa'
a{2,} # 匹配'a两次或两次以上
-
|
或运算符。如果左边或右边的最长图案匹配,则匹配成功。例如:
abc|xyz # 匹配 'abc' and 'xyz'
-
(...)
组成一组。可以使用组将表达式的一部分视为单个字符。例如:
abc(def)? #匹配'abc'和'abcdef',但不匹配'abcd'
-
[...]
匹配括号中的一个字符。例如:
[abc] # 匹配 'a', 'b', 'c'
在括号内,-表示一个范围,除非-是第一个字符或转义。例如:
[a-c] # 匹配'a', 'b', or 'c'
[-abc] # '-'是第一个字符。匹配'-','a', 'b'或'c'
[abc\-] # 转义'-'. 匹配'a', 'b', 'c', or '-'
括号中字符前面的
^
表示该字符或范围为负。例如:[^abc] #匹配除'a', 'b'或'c'以外的任何字符
[^a-c] #匹配除'a', 'b'或'c'以外的任何字符
[^-abc] #匹配除'-','a', 'b'或'c'以外的任何字符
[^abc\-] #匹配除'a', 'b', 'c'或'-'以外的任何字符
配置运算符
您可以使用flags
参数为Lucene的正则表达式引擎启用更多可选操作符。
若要启用多个操作符,请使用|分隔符。例如,flags值为COMPLEMENT|INTERVAL启用了COMPLEMENT和INTERVAL操作符。
有效参数
-
ALL
默认启用所有可选操作符。
-
COMPLEMENT
启用操作符。可以使用对最短的跟随模式求反。例如:
a~bc #匹配“adc”和“aec”,但不匹配“abc”
-
INTERVAL
启用<>操作符。您可以使用<>来匹配数值范围。例如:
foo<1-100> #匹配'foo1', 'foo2'…“foo99”、“foo100”
foo<01-100> #匹配'foo01', 'foo02'…“foo99”、“foo100”
-
INTERSECTION
启用作为AND操作符的&操作符。如果左侧和右侧的模式都匹配,则匹配成功。例如:
aaa+&.+bbb #匹配“aaabbb”
-
ANYSTRING
启用@操作符。你可以使用@来匹配任何完整的字符串。
您可以将@操作符与&和~操作符组合在一起,以创建一个“everything except”逻辑。例如:
@&~(abc.+)匹配除以“abc”开头的词以外的所有内容
不支持的运算符
您可以使用minimum_should_match_script使用脚本定义所需的匹配术语数量。如果需要动态设置所需术语的数量,这很有用。
下面的搜索返回的文档中,programming_languages字段至少包含以下两个术语:
c++ Java PHP
该查询的source参数表示:
- 需要匹配的术语数量不能超过params.num.terms, terms字段中提供的术语数量。
- 需要匹配的术语数量是2,即required_matches字段的值。
GET /job-candidates/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": ["c++", "java", "php"],
"minimum_should_match_script": {
"source": "Math.min(params.num_terms, doc['required_matches'].value)"
},
"boost": 1.0
}
}
}
}
Type query(类型查询)
7.0.0中已弃用。
类型和类型查询已弃用,并且正在被删除。
Wildcard query(通配符查询)
返回包含与通配符模式匹配的术语的文档。
通配符是匹配一个或多个字符的占位符。例如,*通配符匹配零个或多个字符。您可以将通配符与其他字符组合起来创建通配符模式。
下面的搜索将返回用户字段包含以ki开头、以y结尾的词的文档。这些匹配的词可以包括kiy、kity或kimchy。
GET /_search
{
"query": {
"wildcard": {
"user": {
"value": "ki*y",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
wildcard核心参数:
-
要搜索的字段
核心参数:
-
value
(Required, string)您希望在提供的中找到的术语的通配符模式。
该参数支持两个通配符:
?
:匹配任何单个字符*
: 是否可以匹配零个或多个字符,包括一个空字符
避免使用*或?开头模式。这可能会增加查找匹配项所需的迭代次数,并降低搜索性能。
-
boost
(可选,float)用于降低或增加查询的相关性得分的浮点数。默认为1.0。
可以使用boost参数调整包含两个或多个查询的搜索的相关性得分。
Boost值相对于默认值1.0。0到1.0之间的提升值会降低相关性得分。值大于1.0时,相关性得分增加。
-
rewrite
(可选,字符串)用于重写查询的方法。获取有效值和更多信息
minimum_should_match 参数
minimum_should_match参数可能的值:
-
整数
指示一个固定的值,不管可选子句的数量。
如:3
-
负整数
指示可选子句的总数,减去此数应为必填项。
如:-2
-
百分比
指示必需的可选子句总数的这个百分比。从百分比计算出的数字四舍五入后用作最小值。
如:75%
-
负百分比
指示可选子句总数中可以减少的百分比。从百分比计算出的数字是四舍五入,然后从总数中减去以确定最小值。
如:-25%
-
组合
正整数,后面跟着小于号,后面跟着前面提到的任何说明符是一个条件说明。它表示如果可选子句的数量等于(或小于)整数,则它们都是必需的,但如果大于整数,则适用该规范。在这个例子中,如果有1到3个从句,它们都是必需的,但对于4个或4个以上的从句,只有90%是必需的。
如:3<90%
-
多值组合
多个条件规范可以用空格分隔,每个条件规范只对比它前面的数字大的数字有效。在这个例子中:如果有1个或2个条款,两个都是必须的,如果有3-9个条款,除了25%以外都是必须的,如果有9个以上条款,除了3个以外都是必须的。
如:2<-25% 9<-3
在处理百分比时,可以使用负值来获得边缘情况下的不同行为。当处理4个从句时,75%和-25%的意思是一样的,但当处理5个从句时,75%意味着需要3个,而-25%意味着需要4个。
如果基于规范的计算确定不需要可选子句,则在搜索时仍然适用关于布尔查询的通常规则(不包含必选子句的布尔查询仍然必须匹配至少一个可选子句)
无论计算结果是多少,大于可选子句数量的值或小于1的值将永远不会被使用。(即:无论计算结果的结果多低或多高,所需匹配的最小数目永远不会小于1或大于子句的数目。
rewrite 参数
此参数仅供专业用户使用。更改此参数的值可能会影响搜索性能和相关性。
Elasticsearch在内部使用Apache Lucene来增强索引和搜索。在它们的原始形式中,Lucene不能执行以下查询:
- fuzzy
- prefix
- query_string
- regexp
- wildcard
为了执行它们,Lucene将这些查询更改为更简单的形式,例如bool查询或位集。
rewrite决定:
- Lucene如何计算每个匹配文档的相关性分数
- Lucene是否将原始查询更改为bool查询或位集
- 如果更改为bool查询,则包含哪些术语查询子句
有效值
-
constant_score
(默认)使用constant_score_boolean方法减少匹配项。否则,该方法将按顺序查找所有匹配的项,并使用位集返回匹配的文档。
-
constant_score_boolean
为每个文档分配一个等于boost参数的相关性分数。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
此方法会导致最终的bool查询超过indices.query.bool.max_clause_count中的子句限制。如果查询超过这个限制,Elasticsearch将返回一个错误。
-
scoring_boolean
计算每个匹配文档的相关性得分。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
此方法会导致最终的bool查询超过indices.query.bool.max_clause_count中的子句限制。如果查询超过这个限制,Elasticsearch将返回一个错误。
-
top_terms_blended_freq_N
计算每个匹配文档的相关性得分,就好像所有术语都有相同的频率一样。这个频率是所有匹配项的最大频率。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包括对得分最高的N个术语的查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
-
top_terms_boost_N
为每个匹配的文档分配一个等于boost参数的相关性分数。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包含前N个术语的术语查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
-
top_terms_N
计算每个匹配文档的相关性得分。
此方法将原始查询更改为bool查询。此bool查询包含每个匹配项的should子句和term查询。
最后一个bool查询只包括对得分最高的N个术语的查询。
可以使用此方法避免超出indices.query.bool.max_clause_count中的子句限制。
rewrite参数的性能考虑因素
对于大多数用途,我们建议使用constant_score、constant_score_boolean或top_terms_boost_N重写方法。
其他方法计算相关性得分。这些分数计算通常是昂贵的,并且不会改善查询结果。
regular expression synatax(正则表达式)
正则表达式是一种使用占位符(称为操作符)来匹配数据中的模式的方法。
Elasticsearch在以下查询中支持正则表达式:
regexp
query_string
Elasticsearch使用Apache Lucene的正则表达式引擎来解析这些查询。
保留字符
Lucene的正则表达式引擎支持所有Unicode字符。但是,以下字符保留为操作符:
. ? + * | { } [ ] ( ) " \
根据启用的可选操作符,以下字符也可能被保留:
# @ & < > ~
要从字面上使用这些字符之一,请使用前面的反斜杠转义或用双引号将其括起来。例如:
\@
呈现为文字“@”
\\
呈现为文字“\”
"john@smith.com"
呈现为'john@smith.com'
标准运算符
Lucene的正则表达式引擎不使用Perl Compatible regular Expressions (PCRE)库,但它支持以下标准操作符。
-
.
匹配任意字符。例如:
ab. # 匹配'aba', 'abb', 'abz', etc.
-
?
重复上述字符0次或1次。通常用于使前面的字符是可选的。例如:
abc? # 匹配 'ab' and 'abc'
-
+
重复前面的字符一次或多次。例如:
ab+ # 匹配'abb', 'abbb', 'abbbb', etc.
-
*
重复上述字符0次或多次。例如:
ab* # 匹配 'ab', 'abb', 'abbb', 'abbbb', etc.
-
{}
前一个字符可以重复的最小和最大次数。例如:
a{2} # 匹配 'aa'
a{2,4} # 匹配 'aa', 'aaa', and 'aaaa'
a{2,} # 匹配'a两次或两次以上
-
|
或运算符。如果左边或右边的最长图案匹配,则匹配成功。例如:
abc|xyz # 匹配 'abc' and 'xyz'
-
(...)
组成一组。可以使用组将表达式的一部分视为单个字符。例如:
abc(def)? #匹配'abc'和'abcdef',但不匹配'abcd'
-
[...]
匹配括号中的一个字符。例如:
[abc] # 匹配 'a', 'b', 'c'
在括号内,-表示一个范围,除非-是第一个字符或转义。例如:
[a-c] # 匹配'a', 'b', or 'c'
[-abc] # '-'是第一个字符。匹配'-','a', 'b'或'c'
[abc\-] # 转义'-'. 匹配'a', 'b', 'c', or '-'
括号中字符前面的
^
表示该字符或范围为负。例如:[^abc] #匹配除'a', 'b'或'c'以外的任何字符
[^a-c] #匹配除'a', 'b'或'c'以外的任何字符
[^-abc] #匹配除'-','a', 'b'或'c'以外的任何字符
[^abc\-] #匹配除'a', 'b', 'c'或'-'以外的任何字符
配置运算符
您可以使用flags
参数为Lucene的正则表达式引擎启用更多可选操作符。
若要启用多个操作符,请使用|分隔符。例如,flags值为COMPLEMENT|INTERVAL启用了COMPLEMENT和INTERVAL操作符。
有效参数
-
ALL
默认启用所有可选操作符。
-
COMPLEMENT
启用操作符。可以使用对最短的跟随模式求反。例如:
a~bc #匹配“adc”和“aec”,但不匹配“abc”
-
INTERVAL
启用<>操作符。您可以使用<>来匹配数值范围。例如:
foo<1-100> #匹配'foo1', 'foo2'…“foo99”、“foo100”
foo<01-100> #匹配'foo01', 'foo02'…“foo99”、“foo100”
-
INTERSECTION
启用作为AND操作符的&操作符。如果左侧和右侧的模式都匹配,则匹配成功。例如:
aaa+&.+bbb #匹配“aaabbb”
-
ANYSTRING
启用@操作符。你可以使用@来匹配任何完整的字符串。
您可以将@操作符与&和~操作符组合在一起,以创建一个“everything except”逻辑。例如:
@&~(abc.+)匹配除以“abc”开头的词以外的所有内容
不支持的运算符
Lucene的正则表达式引擎不支持锚操作符,比如^(行首)或$(行尾)。要匹配一个词,正则表达式必须匹配整个字符串。