目录
3.3 匹配布尔前缀(Match boolean prefix)
3.5 匹配短语前缀(Match phrase prefix)
查询DSL
Elasticsearch 提供了一个基于 JSON 的完整 Query DSL(Domain Specific Language)来定义查询。将查询 DSL 视为查询的 AST(抽象语法树),由两种类型的子句组成:
-
叶查询子句
-
复合查询子句
复合查询子句包含其他叶查询或复合查询,用于以逻辑方式组合多个查询(例如
bool
ordis_max
查询),或改变它们的行为(例如constant_score
查询)。
查询子句的行为取决于它们是用于 查询上下文还是过滤器上下文。
-
允许昂贵的查询
某些类型的查询通常会因其实现方式而执行缓慢,这会影响集群的稳定性。这些查询可以分类如下:
可以通过将设置的值search.allow_expensive_queries
设置为false
(默认为true
)来阻止此类查询的执行。
1.查询和过滤上下文
相关性分数
默认情况下,Elasticsearch 按相关性分数对匹配的搜索结果进行排序,相关性分数衡量每个文档与查询的匹配程度。
相关性分数是一个正浮点数_score
,在搜索API的元数据字段中返回 。越高 _score
,文档越相关。虽然每种查询类型可以不同地计算相关性分数,但分数计算还取决于查询子句是在查询还是过滤器上下文中运行。
查询上下文
在查询上下文中,查询子句回答了“此文档与此查询子句匹配程度如何?” 除了判断文档是否匹配外,查询子句还会计算_score
元数据字段中的相关性分数 。
查询上下文是有效每当查询子句被传递给一个query
参数,如query
该参数 搜索API。
过滤上下文
在过滤器上下文中,查询子句回答问题“此文档是否与此查询子句匹配?” 答案是简单的“是”或“否”——不计算分数。过滤上下文主要用于过滤结构化数据,例如
-
这是否
timestamp
属于 2015 年至 2016 年的范围? -
该
status
字段是否设置为"published"
?
Elasticsearch 会自动缓存常用的过滤器,以提高性能。
只要将查询子句传递给filter
参数,例如查询中的filter
ormust_not
参数、 bool
查询中的filter
参数 constant_score
或filter
聚合, 过滤上下文就会生效。
查询和过滤上下文示例
以下是在search
API中的查询和过滤上下文中使用的查询子句示例。此查询将匹配满足以下所有条件的文档:
-
该
title
字段包含单词search
。 -
该
content
字段包含单词elasticsearch
。 -
该
status
字段包含确切的词published
。 -
该
publish_date
字段包含从 2015 年 1 月 1 日起的日期。
GET /_search
{
"query": { # 1
"bool": { # 2
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [ # 3
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
1 | 该query 参数表示查询上下文。 |
---|---|
2 | 该bool 两个match 子句查询相关内容,这意味着它们被用来评定每个文档的比赛如何使用。 |
3 | 该filter 参数表示过滤器上下文。它的term and range 子句用于过滤器上下文。它们会过滤掉不匹配的文档,但不会影响匹配文档的分数。 |
-
warning
-
为查询上下文中的查询计算的分数表示为单精度浮点数;它们只有 24 位用于有效数的精度。超过有效数精度的分数计算将被转换为精度损失的浮点数。
-
-
tip
-
对于应该影响匹配文档分数的条件(即文档匹配程度),在查询上下文中使用查询子句,并在过滤器上下文中使用所有其他查询子句。
-
2.复合查询
复合查询包装其他复合查询或叶查询,以组合它们的结果和分数,改变它们的行为,或者从查询切换到过滤上下文。
该组中的查询是:
-
用于组合多个叶或化合物查询子句,作为默认查询
must
,should
,must_not
,或filter
条款。在must
和should
条款有他们的分数相结合-更多的配套条款,更好地-而must_not
和filter
条款在过滤器上下文中执行。 -
返回匹配
positive
查询的文档,但减少也匹配negative
查询的文档的分数。 -
包装另一个查询的查询,但在过滤器上下文中执行它。所有匹配的文档都被赋予相同的“常量”
_score
。 -
接受多个查询并返回与任何查询子句匹配的任何文档的查询。虽然
bool
查询结合了所有匹配查询的分数,但dis_max
查询使用单个最佳匹配查询子句的分数。 -
使用函数修改主查询返回的分数,以考虑流行度、新近度、距离或使用脚本实现的自定义算法等因素。
2.1 布尔查询(Boolean)
匹配与其他查询的布尔组合匹配的文档的查询。bool 查询映射到 Lucene BooleanQuery
。它是使用一个或多个布尔子句构建的,每个子句都有一个类型化的出现。发生类型有:
发生 | 描述 |
---|---|
must | 子句(查询)必须出现在匹配的文档中,并将有助于得分。 |
filter | 子句(查询)必须出现在匹配的文档中。然而 must ,查询的分数将被忽略。过滤器子句在过滤器上下文中执行,这意味着忽略评分并考虑缓存子句。 |
should | 子句(查询)应该出现在匹配的文档中。 |
must_not | 子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着忽略评分并考虑将子句用于缓存。因为评分被忽略,0 所以返回所有文档的评分。 |
的bool
查询需要更匹配就是更好的方法,所以从每个匹配得分must
或should
子句将被加在一起以提供最终的_score
每个文档。
POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user.id" : "kimchy" }
},
"filter": {
"term" : { "tags" : "production" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tags" : "env1" } },
{ "term" : { "tags" : "deployed" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}
使用 minimum_should_match
您可以使用该minimum_should_match
参数来指定should
返回的文档必须匹配的子句数量或百分比。
如果bool
查询至少包含一个should
子句且没有must
or filter
子句,则默认值为1
。否则,默认值为0
。
有关其他有效值,请参阅 minimum_should_match
参数。
得分与 bool.filter
在filter
元素下指定的查询对评分没有影响 - 分数返回为0
。分数仅受已指定查询的影响。例如,以下所有三个查询都返回status
字段包含 term 的所有文档active
。
第一个查询为0
所有文档分配一个分数,因为没有指定评分查询:
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
查询指定的得分1.0
与滤波匹配的所有文件。
GET _search
{
"query": {
"constant_score": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
命名查询
每个查询都_name
在其顶级定义中接受 a 。您可以使用命名查询来跟踪哪些查询与返回的文档匹配。如果使用命名查询,则响应包含matched_queries
每个命中的属性。
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { "name.first": { "query": "shay", "_name": "first" } } },
{ "match": { "name.last": { "query": "banon", "_name": "last" } } }
],
"filter": {
"terms": {
"name.last": [ "banon", "kimchy" ],
"_name": "test"
}
}
}
}
}
2.2 提升查询(Boosting)
返回匹配positive
查询的文档,同时降低也匹配查询的文档 的negative
查询 相关性分数。
您可以使用boosting
查询将某些文档降级而不将它们从搜索结果中排除。
示例请求
GET /_search
{
"query": {
"boosting": {
"positive": {
"term": {
"text": "apple"
}
},
"negative": {
"term": {
"text": "pie tart fruit crumble tree"
}
},
"negative_boost": 0.5
}
}
}
顶级参数
-
positive
(积极)(必需,查询对象)您希望运行的查询。任何返回的文档都必须与此查询匹配。
-
negative
(消极)(必需,查询对象)用于降低匹配文档的相关性分数的查询。如果返回的文档与
positive
查询和此查询匹配,则boosting
查询将计算文档的最终相关性分数,如下所示:从positive
查询中获取原始相关性分数。将分数乘以negative_boost
值。 -
negative_boost
2.3 恒分查询(constant score)
包装过滤器查询并返回相关性分数等于boost
参数值的每个匹配文档。
GET /_search
{
"query": {
"constant_score": {
"filter": {
"term": { "user.id": "kimchy" }
},
"boost": 1.2
}
}
}
constant_score
顶级参数
-
filter
(必需,查询对象)过滤您希望运行的查询。任何返回的文档都必须与此查询匹配。过滤查询不计算相关性分数。为了提高性能,Elasticsearch 会自动缓存常用的过滤器查询。
-
boost
(可选,浮点数)用作与查询匹配的每个文档 的恒定相关性分数的浮点数
filter
。默认为1.0
.
2.4 最大分离度(Disjunction max)
返回匹配一个或多个包装查询的文档,称为查询子句或子句。
如果返回的文档与多个查询子句匹配,则dis_max
查询为文档分配任何匹配子句中最高的相关性分数,并为任何其他匹配子查询分配一个打破平局增量。
您可以使用dis_max
来在映射有不同增强因子的字段中搜索术语 。
示例请求
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "term": { "title": "Quick pets" } },
{ "term": { "body": "Quick pets" } }
],
"tie_breaker": 0.7
}
}
}
高级参数
-
queries
(必需,查询对象数组)包含一个或多个查询子句。返回的文档必须与这些查询中的一个或多个匹配。如果一个文档匹配多个查询,Elasticsearch 使用最高的相关性分数。
-
tie_breaker
(可选,浮点数)之间的浮点数
0
,1.0
用于增加匹配多个查询子句的文档的相关性分数。默认为0.0
.您可以使用该tie_breaker
值为在多个字段中包含相同术语的文档分配比在多个字段中仅包含该术语的文档更高的相关性分数,而不会将此与多个字段中两个不同术语的更好情况混淆.如果一个文档匹配多个子句,则dis_max
查询计算文档的相关性分数如下:从得分最高的匹配子句中获取相关性得分。将任何其他匹配子句的分数乘以该tie_breaker
值。将最高分加到相乘的分数上。如果该tie_breaker
值大于0.0
,则所有匹配的子句都计数,但得分最高的子句计数最多。
2.5 功能评分(Function score)
将function_score
允许你修改的由查询检索文档的分数。例如,如果评分函数的计算成本很高,并且足以计算过滤后的文档集的评分,那么这会很有用。
要使用function_score
,用户必须定义一个查询和一个或多个函数,为查询返回的每个文档计算一个新的分数。
function_score
只能与这样的一个函数一起使用:
GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"random_score": {}, # 1
"boost_mode": "multiply"
}
}
}
1 | 有关支持的函数列表,请参阅函数分数。 |
---|---|
此外,还可以组合多个功能。在这种情况下,可以选择仅在文档与给定的过滤查询匹配时才应用该函数
GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5", # 1
"functions": [
{
"filter": { "match": { "test": "bar" } },
"random_score": {}, # 2
"weight": 23
},
{
"filter": { "match": { "test": "cat" } },
"weight": 42
}
],
"max_boost": 42,
"score_mode": "max",
"boost_mode": "multiply",
"min_score": 42
}
}
}
1 | 提升整个查询。 |
---|---|
2 | 有关支持的函数列表,请参阅函数分数。 |
note | 每个函数的过滤查询产生的分数无关紧要 |
如果函数没有给出过滤器,这相当于指定 "match_all": {}
首先,每个文档都由定义的函数评分。该参数 score_mode
指定如何组合计算的分数:
multiply | 分数相乘(默认) |
---|---|
sum | 分数相加 |
avg | 分数是平均的 |
first | 应用具有匹配过滤器的第一个函数 |
max | 使用最高分 |
min | 使用最低分数 |
因为分数可以在不同的尺度上(例如,对于衰减函数,在 0 和 1 之间,但对于 是任意的field_value_factor
),并且因为有时函数对分数的不同影响是可取的,所以可以使用用户定义的 来调整每个函数的分数 weight
。在weight
可以为每个功能在被定义functions
阵列(上面的例子)和被乘以由相应的函数来计算分数。如果权重在没有任何其他函数声明的情况下给出,则weight
作为一个简单地返回weight
.
如果score_mode
设置为avg
单个分数将通过加权平均组合。例如,如果两个函数返回得分1和2以及它们各自的权重是3和4,那么他们的分数将被组合为 (1*3+2*4)/(3+4)
与不 (1*3+2*4)/2
。
可以通过设置max_boost
参数来限制新的分数不超过某个限制。默认max_boost
值为 FLT_MAX。
新计算的分数与查询的分数相结合。该参数boost_mode
定义了如何:
multiply | 查询分数和函数分数相乘(默认) |
---|---|
replace | 仅使用函数分数,忽略查询分数 |
sum | 添加查询分数和函数分数 |
avg | 平均 |
max | 查询分数和函数分数的最大值 |
min | 查询分数和函数分数的最小值 |
默认情况下,修改分数不会更改匹配的文档。要排除不满足某个分数阈值的文档,min_score
可以将参数设置为所需的分数阈值。
为了min_score
工作,查询返回的所有文档都需要进行评分,然后一一过滤掉。
该function_score
查询提供了多种类型的评分函数。
-
衰减函数:
gauss
,linear
,exp
脚本分数
该script_score
函数允许您包装另一个查询并根据使用脚本表达式从文档中的其他数字字段值派生的计算选择自定义它的评分。这是一个简单的示例:
GET /_search
{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"script_score": {
"script": {
"source": "Math.log(2 + doc['my-int'].value)"
}
}
}
}
}
-
重要的
-
在 Elasticsearch 中,所有文档分数都是 32 位正浮点数。
-
如果该
script_score
函数产生更精确的分数,则将其转换为最接近的 32 位浮点数。 -
同样,分数必须为非负数。否则,Elasticsearch 会返回错误。
-
在不同的脚本字段值和表达式之上, _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['my-int'].value)"
}
}
}
}
}
请注意,与custom_score
查询不同的是,查询的分数乘以脚本评分的结果。如果你想禁止这个,设置"boost_mode": "replace"
重量
该weight
分数可以让你乘上提供的分数 weight
。有时这可能是需要的,因为在特定查询上设置的提升值会被标准化,而对于此评分函数则不会。数字值为 float 类型。
"weight" : number
随机的
random_score
产生被均匀地从0分布直到但不包括1.默认情况下,它采用了内部Lucene的文档ID作为随机源,这是非常有效的,但不幸的是不可再现的,因为文档可能通过合并重新编号分数。
如果您希望分数可重现,可以提供 aseed
和field
。然后将基于此种子、所field
考虑文档的最小值以及基于索引名称和分片 id 计算的盐计算最终分数,以便具有相同值但存储在不同索引中的文档变得不同分数。请注意,位于同一分片内且具有相同值的文档field
将获得相同的分数,因此通常希望使用对所有文档具有唯一值的字段。一个好的默认选择可能是使用 _seq_no
字段,其唯一的缺点是如果文档更新,分数会改变,因为更新操作也会更新_seq_no
字段的值。
可以在不设置字段的情况下设置种子,但这已被弃用,因为这需要在_id
消耗大量内存的字段上加载字段数据。
GET /_search
{
"query": {
"function_score": {
"random_score": {
"seed": 10,
"field": "_seq_no"
}
}
}
}
字段值因子
该field_value_factor
功能允许您使用文档中的字段来影响分数。它类似于使用该script_score
函数,但是,它避免了编写脚本的开销。如果用于多值字段,则在计算中仅使用该字段的第一个值。
举个例子,假设你有一个用数字my-int
字段索引的文档,并希望用这个字段影响文档的分数,一个这样做的例子看起来像:
GET /_search
{
"query": {
"function_score": {
"field_value_factor": {
"field": "my-int",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
}
}
这将转化为以下评分公式:
sqrt(1.2 * doc['my-int'].value)
该field_value_factor
函数有许多选项:
field | 要从文档中提取的字段。 |
---|---|
factor | 与字段值相乘的可选因子,默认为1 。 |
modifier | 应用于字段值的修饰符,可以是以下之一:none , log , log1p , log2p , ln , ln1p , ln2p , square , sqrt , or reciprocal 。默认为none . |
修饰符 | 意义 |
---|---|
none | 不对字段值应用任何乘数 |
log | 取字段值的常用对数。因为如果在 0 和 1 之间的值上使用此函数将返回一个负值并导致错误,所以建议log1p 改用。 |
log1p | 将字段值加 1 并取常用对数 |
log2p | 将字段值加 2 并取常用对数 |
ln | 取字段值的自然对数。因为如果在 0 和 1 之间的值上使用此函数将返回一个负值并导致错误,所以建议ln1p 改用。 |
ln1p | 字段值加1,取自然对数 |
ln2p | 将字段值加2并取自然对数 |
square | 将字段值平方(乘以自身) |
sqrt | 取字段值的平方根 |
reciprocal | 报答字段值,同1/x 那里x 是该字段的值 |
-
missing
如果文档没有该字段,则使用的值。修饰符和因子仍然适用于它,就好像它是从文档中读取的一样。
field_value_score
函数产生的分数必须是非负的,否则会抛出错误。如果将log
andln
修饰符用于 0 到 1 之间的值,将产生负值。请确保使用范围过滤器限制字段的值以避免这种情况,或使用log1p
and ln1p
。
请记住,取 log() 为 0,或取负数的平方根是非法操作,会抛出异常。请务必使用范围过滤器限制字段的值以避免这种情况,或使用 log1p
和ln1p
。
衰减函数
衰减函数使用一个函数对文档进行评分,该函数根据文档的数字字段值与用户给定原点的距离而衰减。这类似于范围查询,但具有平滑的边缘而不是框。
要对具有数字字段的查询使用距离评分,用户必须为每个字段定义 aorigin
和 a scale
。的origin
需要,以限定从该计算出的距离的“中心点”,并且scale
定义衰减率。衰减函数指定为
"DECAY_FUNCTION": { # 1
"FIELD_NAME": { # 2
"origin": "11, 12",
"scale": "2km",
"offset": "0km",
"decay": 0.33
}
}
1 | 本DECAY_FUNCTION 应该是一个linear ,exp 或gauss 。 |
---|---|
2 | 指定的字段必须是数字、日期或地理点字段。 |
在上面的示例中,字段是 ageo_point
并且可以以地理格式提供原点。scale
并且offset
在这种情况下必须与单位一起给出。如果您的字段是日期字段,您可以将scale
and设置offset
为天、周等。例子:
GET /_search
{
"query": {
"function_score": {
"gauss": {
"@timestamp": {
"origin": "2013-09-17", # 1
"scale": "10d",
"offset": "5d", # 2
"decay": 0.5 # 2
}
}
}
}
}
复制为 curl在控制台中查看
1 | 原点的日期格式取决于format 您的映射中定义的。如果未定义原点,则使用当前时间。 |
---|---|
2 | 在offset 和decay 参数都是可选的。 |
origin | 用于计算距离的原点。必须作为数字字段的数字、日期字段的日期和地理字段的地理点给出。地理和数字字段是必需的。对于日期字段,默认值为now . now-1h 原点支持日期数学(例如)。 |
---|---|
scale | 所有类型都需要。定义距原点的距离 + 偏移量,在该距离处计算的分数等于decay 参数。对于地理字段:可以定义为数字+单位(1km、12m、...)。默认单位是米。对于日期字段:可以定义为数字+单位(“1h”、“10d”、...)。默认单位是毫秒。对于数字字段:任何数字。 |
offset | 如果offset 定义了an ,衰减函数将只计算距离大于定义的文档的衰减函数 offset 。默认值为 0。 |
decay | 该decay 参数定义了如何在给定的距离处对文档进行评分scale 。如果没有decay 定义,远处的文档 scale 将被评分为 0.5。 |
在第一个示例中,您的文档可能表示酒店并包含地理位置字段。您想根据酒店距给定位置的距离计算衰减函数。您可能不会立即看到为高斯函数选择什么尺度,但您可以这样说:“在距离所需位置 2 公里处,分数应该减少到三分之一。” 然后将自动调整参数“scale”,以确保得分函数为距离所需位置 2 公里的酒店计算得分为 0.33。
在第二个示例中,字段值在 2013-09-12 和 2013-09-22 之间的文档的权重为 1.0,而距该日期 15 天的文档的权重为 0.5。
支持的衰减函数
所述DECAY_FUNCTION
确定衰减的形状:
-
gauss
正常衰减,计算如下:
其中
被计算以确保得分取值
decay
在距离scale
从origin
+ -offset
有关演示函数生成的曲线的图表,
gauss
请参阅Normal 衰减,关键字gauss
。 -
exp
指数衰减,计算如下:
其中再次参数
被计算,以确保该得分取值
decay
在距离scale
从origin
+ -offset
有关演示函数生成的曲线的图表,
exp
请参阅指数衰减,关键字exp
。 -
linear
线性衰减,计算如下:
.其中再次参数
s
被计算,以确保该得分取值decay
在距离scale
从origin
+ -offset
与正常和指数衰减相反,如果字段值超过用户给定比例值的两倍,该函数实际上将分数设置为 0。
对于单个函数,三个衰减函数及其参数可以像这样可视化(本示例中的字段称为“年龄”):
多值字段
如果用于计算衰减的字段包含多个值,则默认选择最接近原点的值来确定距离。这可以通过设置来改变multi_value_mode
。
min | 距离是最小距离 |
---|---|
max | 距离是最大距离 |
avg | 距离是平均距离 |
sum | 距离是所有距离的总和 |
例子:
"DECAY_FUNCTION" : { "FIELD_NAME" : { "origin" : ..., "scale" : ... }, "multi_value_mode" : "avg" }
详细示例
假设您正在某个城镇寻找旅馆。您的预算有限。此外,您希望酒店靠近市中心,因此酒店离所需位置越远,您入住的可能性就越小。
您希望与您的标准(例如,“酒店、南希、非吸烟者”)匹配的查询结果根据到市中心的距离和价格进行评分。
直觉上,你想把镇中心定义为原点,也许你愿意从酒店步行2公里到镇中心。 在这种情况下,位置字段的原点是镇中心,比例尺约为 2 公里。
如果您的预算很低,您可能更喜欢便宜的东西而不是昂贵的东西。对于价格字段,来源为 0 欧元,比例取决于您愿意支付的金额,例如 20 欧元。
在此示例中,对于酒店的价格,这些字段可能被称为“price”,对于这家酒店的坐标可能被称为“location”。
price
在这种情况下的功能是
"gauss": { # 1
"price": {
"origin": "0",
"scale": "20"
}
}
1 | 这个衰减函数也可以是linear 或exp 。 |
---|---|
和location
:
"gauss": { # 1
"location": {
"origin": "11, 12",
"scale": "2km"
}
}
1 | 这个衰减函数也可以是linear 或exp 。 |
---|---|
假设您想将这两个函数与原始分数相乘,请求将如下所示:
GET /_search
{
"query": {
"function_score": {
"functions": [
{
"gauss": {
"price": {
"origin": "0",
"scale": "20"
}
}
},
{
"gauss": {
"location": {
"origin": "11, 12",
"scale": "2km"
}
}
}
],
"query": {
"match": {
"properties": "balcony"
}
},
"score_mode": "multiply"
}
}
}
接下来,我们将展示三个可能的衰减函数中每一个的计算得分的样子。
正常衰减,关键字 gauss
在上例中选择gauss
衰减函数时,乘法器的等高线和曲面图如下所示:
假设您的原始搜索结果与三个酒店匹配:
-
“后背小睡”
-
“酒后驾车”
-
“BnB 贝尔维尤”。
“Drink n Drive”离您定义的位置很远(近 2 公里),而且价格也不便宜(约 13 欧元),因此它的系数很低,为 0.56。“BnB Bellevue”和“Backback Nap”都非常接近定义的位置,但“BnB Bellevue”更便宜,因此乘数为 0.86,而“Backback Nap”的乘数为 0.66。
指数衰减,关键字 exp
在上例中选择exp
衰减函数时,乘法器的等高线和曲面图如下所示:
线性衰减,关键字 linear
在上例中选择linear
衰减函数时,乘法器的等高线和曲面图如下所示:
衰减函数支持的字段
仅支持数字、日期和地理点字段。
如果缺少字段怎么办?
如果文档中缺少数字字段,该函数将返回 1。
3.全文搜索(Full text queries)
全文查询使您能够搜索分析过的文本字段,例如电子邮件正文。使用在索引期间应用于字段的相同分析器处理查询字符串。
该组中的查询是:
-
允许对匹配项的排序和接近度进行细粒度控制的全文查询。
-
用于执行全文查询的标准查询,包括模糊匹配和短语或邻近查询。
-
创建一个
bool
查询,匹配每个词作为term
查询,最后一个词除外,作为prefix
查询 匹配 -
类似于
match
查询,但用于匹配精确的短语或单词接近匹配。 -
像
match_phrase
查询一样,但对最后一个词进行通配符搜索。 -
match
查询 的多字段版本。 -
匹配多个字段,就好像它们已被索引到一个组合字段中一样。
-
支持简洁的 Lucene查询字符串语法,允许您在单个查询字符串中指定 AND|OR|NOT 条件和多字段搜索。仅供专家用户使用。
-
一种更简单、更健壮的
query_string
语法版本,适合直接向用户公开。
3.1 区间查询(intervals)
根据匹配项的顺序和接近程度返回文档。
该intervals
查询使用的匹配规则,从一小部分的定义构造。然后将这些规则应用于指定field
.
定义产生跨越文本正文中的术语的最小间隔序列。这些间隔可以通过父源进一步组合和过滤。
示例请求
以下intervals
搜索返回包含my favorite food
没有任何间隙的文档,后跟hot water
或cold porridge
在 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>
(必需,规则对象)要搜索的字段。该参数的值是一个规则对象,用于根据匹配项、顺序和接近度来匹配文档。有效规则包括:
match
match
规则参数
该match
规则匹配分析的文本。
-
query
(必需,字符串)您希望在提供的
<field>
. -
max_gaps
(可选,整数)匹配项之间的最大位置数。比这更远的术语不被视为匹配。默认为
-1
.如果未指定或设置为-1
,则匹配没有宽度限制。如果设置为0
,则术语必须彼此相邻出现。 -
ordered
(可选,布尔值)如果
true
,匹配项必须按其指定顺序出现。默认为false
. -
analyzer
(可选,字符串)分析器用于分析
query
. 默认为顶级<field>
的分析器。 -
filter
(可选,间隔过滤规则对象)一个可选的间隔过滤器。
-
use_field
(可选,字符串)如果指定,则匹配来自此字段而不是顶级 的间隔
<field>
。使用该字段中的搜索分析器分析术语。这允许您跨多个字段进行搜索,就好像它们都是相同的字段一样;例如,您可以将相同的文本索引到词干和非词干字段中,并在非词干标记附近搜索词干标记。
prefix
规则参数
该prefix
规则匹配以指定字符集开头的术语。此前缀可以扩展以匹配最多 128 个术语。如果前缀匹配超过 128 个术语,Elasticsearch 将返回错误。您可以使用index-prefixes
字段映射中的 选项来避免此限制。
-
prefix
(必需,字符串)您希望在顶级
<field>
. -
analyzer
(可选,字符串)分析器用于规范化
prefix
. 默认为顶级<field>
的分析器。 -
use_field
(可选,字符串)如果指定,则匹配来自此字段而不是顶级 的间隔
<field>
。prefix
使用此字段中的搜索分析器对进行标准化,除非analyzer
指定了单独的。
wildcard
规则参数
该wildcard
规则使用通配符模式匹配术语。此模式可以扩展以匹配最多 128 个术语。如果模式匹配超过 128 个术语,Elasticsearch 将返回错误。
-
pattern
(必需,字符串)用于查找匹配项的通配符模式。此参数支持两个通配符运算符:
?
, 匹配任何单个字符*
, 可以匹配零个或多个字符,包括空字符避免以*
或开始模式?
。这会增加查找匹配项所需的迭代次数并降低搜索性能。 -
analyzer
(可选,字符串)分析器用于规范化
pattern
. 默认为顶级<field>
的分析器。 -
use_field
(可选,字符串)如果指定,则匹配来自此字段而不是顶级 的间隔
<field>
。的pattern
是使用搜索分析器从这个领域规格化,除非analyzer
单独指定。
fuzzy
规则参数
该fuzzy
规则在Fuzziness定义的编辑距离内匹配与提供的术语相似的术语。如果模糊扩展匹配超过 128 个术语,Elasticsearch 将返回错误。
-
term
(必需,字符串)要匹配的术语
-
prefix_length
(可选,整数)创建扩展时保持不变的起始字符数。默认为
0
. -
transpositions
(可选,布尔值)指示编辑是否包括两个相邻字符的换位(ab → ba)。默认为
true
. -
fuzziness
(可选,字符串)允许匹配的最大编辑距离。有关 有效值和更多信息,请参阅模糊度。默认为
auto
. -
analyzer
(可选,字符串)分析器用于规范化
term
. 默认为顶级<field>
的分析器。 -
use_field
(可选,字符串)如果指定,则匹配来自此字段而不是顶级 的间隔
<field>
。的term
是使用搜索分析器从这个领域规格化,除非analyzer
单独指定。
all_of
规则参数
该all_of
规则返回跨越其他规则组合的匹配项。
-
intervals
(必需,规则对象数组)要组合的规则数组。所有规则都必须在文档中生成匹配项,以便整体源进行匹配。
-
max_gaps
(可选,整数)匹配项之间的最大位置数。规则产生的间隔比这更远不被视为匹配。默认为
-1
.如果未指定或设置为-1
,则匹配没有宽度限制。如果设置为0
,则术语必须彼此相邻出现。 -
ordered
(可选,布尔值)如果
true
,规则产生的间隔应按指定的顺序出现。默认为false
. -
filter
(可选,区间过滤规则对象)用于过滤返回区间的规则。
any_of
规则参数
该any_of
规则返回由其任何子规则产生的区间。
-
intervals
(必需,规则对象数组)要匹配的规则数组。
-
filter
(可选,区间过滤规则对象)用于过滤返回区间的规则。
filter
规则参数
该filter
规则根据查询返回间隔。有关示例,请参阅 过滤器示例。
-
after
(可选,查询对象)查询用于返回遵循
filter
规则间隔的间隔。 -
before
(可选,查询对象)用于返回
filter
规则中间隔之前发生的间隔的查询。 -
contained_by
(可选,查询对象)用于返回
filter
规则中的区间所包含的区间的查询。 -
containing
(可选,查询对象)用于返回包含
filter
规则区间的区间的查询。 -
not_contained_by
(可选,查询对象)用于返回不 包含在
filter
规则间隔中的间隔的查询。 -
not_containing
(可选,查询对象)用于返回不包含
filter
规则区间的区间的查询。 -
not_overlapping
(可选,查询对象)用于返回与规则中的间隔不重叠的间隔的查询
filter
。 -
overlapping
(可选,查询对象)用于返回与
filter
规则中的间隔重叠的间隔的查询。 -
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"
}
}
}
}
}
}
}
}
脚本过滤器
您可以使用脚本根据开始位置、结束位置和内部间隙计数过滤间隔。下面的filter
脚本使用 interval
与变量start
,end
和gaps
方法:
POST _search
{
"query": {
"intervals" : {
"my_text" : {
"match" : {
"query" : "hot porridge",
"filter" : {
"script" : {
"source" : "interval.start > 10 && interval.end < 20 && interval.gaps == 0"
}
}
}
}
}
}
}
最小化
间隔查询总是最小化间隔,以确保查询可以在线性时间内运行。这有时会导致令人惊讶的结果,尤其是在使用max_gaps
限制或过滤器时。例如,采用以下查询,搜索salty
包含在短语中的内容hot porridge
:
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
. 考虑下面的查询,搜索the
紧跟big
或big bad
紧随其后,紧随其后wolf
:
POST _search
{
"query": {
"intervals" : {
"my_text" : {
"all_of" : {
"intervals" : [
{ "match" : { "query" : "the" } },
{ "any_of" : {
"intervals" : [
{ "match" : { "query" : "big" } },
{ "match" : { "query" : "big bad" } }
] } },
{ "match" : { "query" : "wolf" } }
],
"max_gaps" : 0,
"ordered" : true
}
}
}
}
}
与直觉相反,这个查询与文档不匹配the big bad wolf
,因为any_of
中间的规则只产生间隔 for big
-big bad
比 for 更长的间隔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 } }
]
}
}
}
}
}
3.2 匹配查询(match)
返回与提供的文本、数字、日期或布尔值匹配的文档。在匹配之前分析提供的文本。
该match
查询是执行全文搜索的标准查询,包括用于模糊匹配的选项。
示例请求
GET /_search
{
"query": {
"match": {
"message": {
"query": "this is a test"
}
}
}
}
match参数
-
query
(必需)您希望在提供的
<field>
.在执行搜索之前,match
查询会分析任何提供的文本。这意味着match
查询可以搜索text
分析标记的字段,而不是精确的术语。 -
analyzer
(可选,字符串)分析器用于将
query
值中的文本转换为标记。默认为为映射的索引时间分析器<field>
。如果没有映射分析器,则使用索引的默认分析器。 -
auto_generate_synonyms_phrase_query
(可选,布尔值)如果
true
, 则为多词同义词自动创建匹配短语查询。默认为true
.有关示例,请参阅在匹配查询中使用同义词。 -
fuzziness
-
max_expansions
(可选,整数)查询将扩展到的最大术语数。默认为
50
. -
prefix_length
(可选,整数)用于模糊匹配的起始字符数保持不变。默认为
0
. -
fuzzy_transpositions
(可选,布尔值)如果
true
,模糊匹配的编辑包括两个相邻字符的换位(ab → ba)。默认为true
. -
fuzzy_rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅
rewrite
参数。如果fuzziness
参数不是0
,则match
查询默认使用 的fuzzy_rewrite
方法top_terms_blended_freqs_${max_expansions}
。 -
lenient
(可选,布尔值)如果,则忽略
true
基于格式的错误,例如为数字字段提供文本query
值。默认为.false
-
operator
(可选,字符串)用于解释
query
值中文本的布尔逻辑。有效值为:OR
(默认)例如,query
值capital of Hungary
被解释为capital OR of OR Hungary
。AND
例如,query
值capital of Hungary
被解释为capital AND of AND Hungary
。 -
minimum_should_match
(可选,字符串)必须与要返回的文档匹配的最小子句数。有关有效值和更多信息,请参阅
minimum_should_match
参数。 -
zero_terms_query
(可选,字符串)指示如果
analyzer
删除所有标记(例如使用stop
过滤器时),是否不返回任何文档。有效值为:none
(默认)如果analyzer
删除所有令牌,则不会返回任何文档。all
返回所有文档,类似于match_all
查询。有关示例,请参阅零项查询。
笔记
简短请求示例
您可以通过组合<field>
和query
参数来简化匹配查询语法。例如:
GET /_search
{
"query": {
"match": {
"message": "this is a test"
}
}
}
匹配查询的工作原理
该match
查询类型boolean
。这意味着对提供的文本进行分析,分析过程根据提供的文本构造一个布尔查询。该operator
参数可以设置为or
或and
来控制布尔子句(默认为or
)。should
可以使用minimum_should_match
参数设置要匹配的可选子句 的最小数量。
这是带有operator
参数的示例:
GET /_search
{
"query": {
"match": {
"message": {
"query": "this is a test",
"operator": "and"
}
}
}
}
所述analyzer
可以被设置为控制哪个分析器将在文本上执行的分析过程。它默认为字段显式映射定义,或默认搜索分析器。
该lenient
参数可以设置为true
忽略由数据类型不匹配引起的异常,例如尝试使用文本查询字符串查询数字字段。默认为false
.
匹配查询中的模糊性
fuzziness
允许基于被查询的字段类型进行模糊匹配。有关允许的设置,请参阅模糊度。
的prefix_length
和 max_expansions
可以在这种情况下,以控制模糊处理来设定。如果设置了模糊选项,则查询将top_terms_blended_freqs_${max_expansions}
用作其重写方法,该fuzzy_rewrite
参数允许控制如何重写查询。
默认情况下允许模糊换位 ( ab
→ ba
),但可以通过设置fuzzy_transpositions
为来禁用false
。
模糊匹配不适用于具有同义词的术语或分析过程在同一位置产生多个标记的情况。在幕后,这些术语被扩展为一个特殊的同义词查询,它混合了术语频率,不支持模糊扩展。
GET /_search
{
"query": {
"match": {
"message": {
"query": "this is a testt",
"fuzziness": "AUTO"
}
}
}
}
零词查询
如果使用的分析器像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"
}
}
}
}
截止频率(7.3.0 中已弃用)
可以省略此选项,因为Match可以有效地跳过文档块,而无需任何配置,前提是不跟踪命中总数。
匹配查询支持cutoff_frequency
允许指定绝对或相对文档频率,其中高频词被移动到可选的子查询中,并且只有在or
操作符的情况下低频词(低于截止值)之一 或所有在and
运算符匹配的情况下的低频项。
此查询允许stopwords
在运行时动态处理,独立于域并且不需要停用词文件。它可以防止对高频词进行评分/迭代,并且仅在更重要/较低频率的词与文档匹配时才考虑这些词。然而,如果所有查询词都高于给定的查询词,则cutoff_frequency
该查询会自动转换为纯连词 ( and
) 查询以确保快速执行。
的cutoff_frequency
可以是相对于文件的总数,如果在范围从0(含)到1(不包括)或绝对如果大于或等于 1.0
。
这是一个示例,显示了专门由停用词组成的查询:
GET /_search
{
"query": {
"match": {
"message": {
"query": "to be or not to be",
"cutoff_frequency": 0.001
}
}
}
}
该cutoff_frequency
选项在每个分片级别上运行。这意味着当在文档编号较低的测试索引上进行尝试时,您应该遵循相关性中的建议已被破坏。
同义词
该match
查询支持使用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
匹配带有 termny
或连词的文档new AND york
。默认情况下,该参数auto_generate_synonyms_phrase_query
设置为true
。
"query" : {
"match" : {
"status":{
"query" : "push"
}
}
},
3.3 匹配布尔前缀(Match boolean prefix)
一match_bool_prefix
查询分析其输入,并构造 bool
查询从条款。除了最后一个术语外,每个术语都用于term
查询。最后一项用于prefix
查询。一个 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
和operator
参数,如 match
查询所述,将设置应用于构造的bool
查询。bool
在大多数情况下,构造查询中的子句数量将是通过分析查询文本产生的术语数量。
fuzziness
,prefix_length
, max_expansions
,fuzzy_transpositions
,和fuzzy_rewrite
参数可被应用到term
所有术语,而是最终术语构建子查询。它们对为最终术语构造的前缀查询没有任何影响。
3.4 匹配短语(Match phrase)
该match_phrase
查询分析文本,并创建一个phrase
查询出来的分析文字。例如:
GET /_search
{
"query": {
"match_phrase": {
"message": "this is a test"
}
}
}
短语查询slop
以任何顺序匹配最多可配置(默认为 0)的术语。转置项的斜率为 2。
所述analyzer
可以被设置为控制哪个分析器将在文本上执行的分析过程。它默认为字段显式映射定义,或默认搜索分析器,例如:
GET /_search
{
"query": {
"match_phrase": {
"message": {
"query": "this is a test",
"analyzer": "my_analyzer"
}
}
}
}
此查询也接受zero_terms_query
,如match
查询中所述。
3.5 匹配短语前缀(Match phrase prefix)
以与提供的相同的顺序返回包含提供的文本的单词的文档。提供的文本的最后一个术语被视为 前缀,匹配以该术语开头的任何单词。
示例请求
以下搜索返回包含字段quick brown f
中以开头的短语的文档 message
。
此搜索将匹配或但不匹配的message
值。quick brown fox
、two quick brown ferrets
、the fox is quick and brown
GET /_search
{
"query": {
"match_phrase_prefix": {
"message": {
"query": "quick brown f"
}
}
}
}
参数
-
query
(必需,字符串)您希望在提供的
<field>
.在执行搜索之前,match_phrase_prefix
查询将任何提供的文本分析为标记。该文本的最后一个术语被视为 前缀,匹配以该术语开头的任何单词。 -
analyzer
(可选,字符串)分析器用于将
query
值中的文本转换为标记。默认为为映射的索引时间分析器<field>
。如果没有映射分析器,则使用索引的默认分析器。 -
max_expansions
(可选,整数)值的最后提供的术语
query
将扩展到的最大术语数。默认为50
. -
slop
(可选,整数)匹配标记之间允许的最大位置数。默认为
0
. 转置项的斜率为2
。 -
zero_terms_query
(可选,字符串)指示如果
analyzer
删除所有标记(例如使用stop
过滤器时),是否不返回任何文档。有效值为:none
(默认)如果analyzer
删除所有令牌,则不会返回任何文档。all
返回所有文档,类似于match_all
查询。
笔记
使用匹配短语前缀查询进行搜索自动完成
虽然易于设置,但使用match_phrase_prefix
搜索自动完成查询有时会产生令人困惑的结果。
例如,考虑查询字符串quick brown f
。这个查询的工作原理是从quick
and创建一个短语查询brown
(即术语quick
必须存在并且必须跟在术语 之后brown
)。然后它查看已排序的术语字典以查找以 开头的前 50 个术语,f
并将这些术语添加到短语查询中。
问题是前 50 个术语可能不包含该术语,fox
因此quick brown fox
不会找到该短语。这通常不是问题,因为用户会继续输入更多字母,直到出现他们要查找的单词。
有关按您类型搜索的更好解决方案,请参阅 完成建议器和search_as_you_type
字段类型。
3.6 组合字段(Combined fields)
该combined_fields
查询支持搜索多个文本字段,就好像它们的内容已被索引到一个组合字段中一样。它采用以术语为中心的查询视图:首先将查询字符串分析为单独的术语,然后在任何字段中查找每个术语。当匹配可以跨越多个文本字段时,此查询特别有用,例如文章的title
、 abstract
和body
:
GET /_search
{
"query": {
"combined_fields" : {
"query": "database systems",
"fields": [ "title", "abstract", "body"],
"operator": "and"
}
}
}
该combined_fields
查询采用基于概率相关性框架:BM25 及其他中描述的简单 BM25F 公式的原则性方法进行评分 。当对匹配进行评分时,查询会跨字段组合术语和集合统计信息。这允许它对每个匹配进行评分,就好像指定的字段已被索引到单个组合字段中一样。(请注意,这是最好的尝试—— combined_fields
做一些近似,分数不会完全服从这个模型。)
-
WARNING
-
字段数限制
一次可以查询的字段数是有限制的。它由 默认为 1024的
indices.query.bool.max_clause_count
搜索设置定义。
-
字段提升
可以使用字符 ( ^
) 表示法提升单个字段:
GET /_search
{
"query": {
"combined_fields" : {
"query" : "distributed consensus",
"fields" : [ "title^2", "body" ]
}
}
}
根据组合场模型解释场增强。例如,如果该title
字段的 boost 为 2,则计算分数时,就好像标题中的每个术语在合成组合字段中出现两次一样。
该combined_fields
查询要求场提升是大于或等于1.0。场增强可以是小数。
参数
-
fields
(必需,字符串数组)要搜索的字段列表。允许字段通配符模式。仅
text
支持字段,并且它们都必须具有相同的 searchanalyzer
。 -
query
(必需,字符串)要在提供的
<fields>
.该combined_fields
查询分析执行搜索之前所提供的文本。 -
auto_generate_synonyms_phrase_query
(可选,布尔值)如果
true
, 则为多术语同义词自动创建匹配短语查询。默认为true
.有关示例,请参阅在匹配查询中使用同义词。 -
operator
(可选,字符串)用于解释
query
值中文本的布尔逻辑。有效值为:or
(默认)例如,query
值database systems
被解释为database OR systems
。and
例如,query
值database systems
被解释为database AND systems
。 -
minimum_should_match
(可选,字符串)必须与要返回的文档匹配的最小子句数。有关有效值和更多信息,请参阅
minimum_should_match
参数。 -
zero_terms_query
(可选,字符串)指示如果
analyzer
删除所有标记(例如使用stop
过滤器时),是否不返回任何文档。有效值为:none
(默认)如果analyzer
删除所有令牌,则不会返回任何文档。all
返回所有文档,类似于match_all
查询。有关示例,请参阅零项查询。
与multi_match
查询的比较
该combined_fields
查询提供了一种跨多个text
字段进行匹配和评分的原则性方法。为了支持这一点,它要求所有字段都具有相同的 search analyzer
。
如果您想要处理不同类型字段(如关键字或数字)的单个查询,那么该multi_match
查询可能更合适。它支持文本和非文本字段,并接受不共享相同分析器的文本字段。
主要multi_match
模式best_fields
和most_fields
以字段为中心的查询视图。相反,combined_fields
以术语为中心:operator
并且minimum_should_match
按术语应用,而不是按字段应用。具体来说,像这样的查询
GET /_search
{
"query": {
"combined_fields" : {
"query": "database systems",
"fields": [ "title", "abstract"],
"operator": "and"
}
}
}
被执行为
+(combined("database", fields:["title" "abstract"]))
+(combined("systems", fields:["title", "abstract"]))
换句话说,每个术语必须至少出现在一个字段中才能匹配文档。
该cross_fields
multi_match
模式还采用以术语为中心的方法并应用operator
和minimum_should_match per-term
。combined_fields
over的主要优点 cross_fields
是其基于 BM25F 算法的稳健且可解释的评分方法。
-
自定义相似之处
3.7 多匹配(Multi-match)
在multi_match
查询基础上的match
查询 ,允许多领域的查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "this is a test", # 1
"fields": [ "subject", "message" ] # 2
}
}
}
1 | 查询字符串。 |
---|---|
2 | 要查询的字段。 |
fields
和字段提升
可以使用通配符指定字段,例如:
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ] # 1
}
}
}
1 | 查询title ,first_name 和last_name 字段。 |
---|---|
可以使用字符 ( ^
) 表示法提升单个字段:
GET /_search
{
"query": {
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ]
}
}
}
1 | 查询将subject 字段的分数乘以 3,但保持 message 字段的分数不变。 |
---|---|
如果没有fields
提供,则multi_match
查询默认为index.query.default_field
索引设置,而后者默认为*
。*
提取映射中符合术语查询条件的所有字段并过滤元数据字段。然后组合所有提取的字段以构建查询。
一次可以查询的字段数是有限制的。它由 默认为 1024的indices.query.bool.max_clause_count
搜索设置定义。
multi_match
查询类型
multi_match
内部执行查询的方式取决于type
参数,可以设置为:
best_fields | (默认) 查找与任何字段匹配的文档,但使用_score 来自最佳字段的文档 。见best_fields 。 |
---|---|
most_fields | 查找与任何字段匹配的文档并组合_score 来自每个字段的 。见most_fields 。 |
cross_fields | 像对待analyzer 一个大字段一样对待字段。在任何 字段中查找每个单词。见cross_fields 。 |
phrase | match_phrase 对每个字段 运行查询并使用_score 来自最佳字段的查询。见phrase 和phrase_prefix 。 |
phrase_prefix | match_phrase_prefix 对每个字段 运行查询并使用_score 来自最佳字段的查询。见phrase 和phrase_prefix 。 |
bool_prefix | match_bool_prefix 在每个字段上 创建一个查询并组合_score 来自每个字段的 。见 bool_prefix 。 |
1.best_fields
field-centric查询:字段中心式匹配
多个字段中,返回评分最高的
best_fields
当您搜索在同一字段中最容易找到的多个词时,该类型最有用。例如,单个字段中的“brown fox”比一个字段中的“brown”和另一个字段中的“fox”更有意义。
该best_fields
类型为每个字段生成一个match
查询并将它们包装在一个dis_max
查询中,以找到单个最佳匹配字段。例如,这个查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "brown fox",
"type": "best_fields",
"fields": [ "subject", "message" ],
"tie_breaker": 0.3
}
}
}
将被执行为:
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "subject": "brown fox" }},
{ "match": { "message": "brown fox" }}
],
"tie_breaker": 0.3
}
}
}
通常best_fields
类型使用单个最佳匹配字段的分数,但如果tie_breaker
指定,则它计算分数如下:
-
来自最佳匹配字段的分数
-
加上
tie_breaker * _score
所有其他匹配字段
此外,接受analyzer
, boost
, operator
, minimum_should_match
, fuzziness
, lenient
, prefix_length
, max_expansions
, fuzzy_rewrite
, zero_terms_query
, cutoff_frequency
,auto_generate_synonyms_phrase_query
和fuzzy_transpositions
,如match query 中所述。
-
重要
-
operator
和minimum_should_match
-
该
best_fields
和most_fields
类型是field-centric -他们针对每个字段生成一个匹配查询。这意味着operator
和minimum_should_match
参数单独应用于每个字段,这可能不是您想要的。
-
-
以这个查询为例:
-
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" # 1 } } }
-
1 所有字符串都必须存在 即 Will Smith不可缺失
-
-
此查询执行为:
-
(+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
-
-
换句话说,所有术语都必须出现在单个字段中才能匹配文档。
-
该
combined_fields
查询提供了一个term-centric的方法来处理operator
,并minimum_should_match
在per-term的基础。另一种多匹配模式cross_fields
也解决了这个问题。
-
2.most_fields
field-centric查询:字段中心式匹配
匹配多个字段,返回的综合评分
most_fields
当查询包含以不同方式分析的相同文本的多个字段时,该类型最有用。例如,主字段可能包含同义词、词干和没有变音符号的术语。第二个字段可能包含original
,第三个字段可能包含shingles
。通过结合所有三个字段的分数,我们可以将尽可能多的文档与主字段匹配,但使用第二个和第三个字段将最相似的结果推送到列表顶部。
这个查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "quick brown fox",
"type": "most_fields",
"fields": [ "title", "title.original", "title.shingles" ]
}
}
}
将被执行为:
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "quick brown fox" }},
{ "match": { "title.original": "quick brown fox" }},
{ "match": { "title.shingles": "quick brown fox" }}
]
}
}
}
每个match
子句的分数相加,然后除以match
子句的数量。
此外,接受analyzer
, boost
, operator
, minimum_should_match
, fuzziness
, lenient
, prefix_length
, max_expansions
, fuzzy_rewrite
, zero_terms_query
and cutoff_frequency
,如match query 中所述,但 请参阅operator
andminimum_should_match
。
3.phrase
和 phrase_prefix
该phrase
和phrase_prefix
类型的行为很像best_fields
,但它们使用match_phrase
或match_phrase_prefix
查询,而不是一个的 match
查询。
这个查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "quick brown f",
"type": "phrase_prefix",
"fields": [ "subject", "message" ]
}
}
}
将被执行为:
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match_phrase_prefix": { "subject": "quick brown f" }},
{ "match_phrase_prefix": { "message": "quick brown f" }}
]
}
}
}
此外,接受analyzer
,boost
,lenient
和zero_terms_query
如在解释匹配,以及slop
其中解释匹配短语。类型phrase_prefix
另外接受max_expansions
.
-
重要
-
phrase
,phrase_prefix
和fuzziness
-
该
fuzziness
参数不能与phrase
orphrase_prefix
类型一起使用。
-
-
4.cross_fields
term-centric查询:词中心式匹配
跨字段匹配 - 待查询内容在多个字段中都显示
该cross_fields
类型对结构化文档特别有用,像shuld match查询。例如,当查询first_name
和last_name
字段中的“Will Smith”时,最佳匹配很可能是一个字段中包含“Will”而在另一个字段中包含“Smith”。
-
这听起来像是
most_fields
的工作,但这种方法有两个问题。第一个问题是operator
和minimum_should_match
是按字段应用的,而不是按术语应用的(参见 上面的解释)。
-
第二个问题与相关性有关:
first_name
和last_name
字段中不同的词频会产生意想不到的结果。
-
例如,假设我们有两个人:“Will Smith”和“Smith Jones”。“Smith”作为姓氏很常见(因此重要性较低),但“Smith”作为名字非常不常见(因此非常重要)。
-
如果我们搜索“Will Smith”,则“Smith Jones”文档可能会出现在更匹配的“Will Smith”之上,因为
first_name:smith
的得分大于first_name:will
+last_name:smith
。
处理这些类型的查询的一种方法是简单地将first_name
和last_name
字段索引 到单个full_name
字段中。当然,这只能在索引时完成。
该cross_field
类型试图通过采用以term-centric方法在查询时解决这些问题 。它首先将查询字符串分析为单独的术语,然后在任何字段中查找每个术语,就好像它们是一个大字段一样。
像这样的查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
}
执行如下:
+(first_name:will last_name:will)
+(first_name:smith last_name:smith)
换句话说,所有术语必须至少出现在一个字段中才能匹配文档。(将此与用于best_fields
和的逻辑most_fields
进行比较 。)
这解决了两个问题之一。不同词频的问题是通过混合所有领域的词频来解决的,以消除差异。
在实践中,first_name:smith
将被视为与 具有相同的频率last_name:smith
,加一。这将使匹配 first_name
并last_name
具有可比的分数,last_name
因为它是最有可能包含smith
.
请注意,这cross_fields
通常仅对都具有boost
of 的短字符串字段有用1
。否则,提高、术语频率和长度归一化会以这样一种方式对分数做出贡献,以至于术语统计的混合不再有意义。
如果您通过Validate运行上述查询,它会返回以下解释:
+blended("will", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
此外,接受analyzer
,boost
,operator
,minimum_should_match
, lenient
,zero_terms_query
和cutoff_frequency
,如解释 匹配查询。
-
警告
-
该
cross_fields
类型以一种并不总是产生格式良好的分数(例如分数可能变为负数)的方式混合字段统计信息。作为替代方案,您可以考虑combined_fields
查询,它也是以术语为中心的,但以更可靠的方式结合了字段统计信息。
-
cross_field
和分析
该cross_field
类型只能在具有相同分析器的字段上以词中心匹配的模式下工作。如上例所示,具有相同分析器的字段组合在一起。如果有多个组,查询将使用任何组中的最佳分数。
例如,如果我们有一个first
和last
字段,它们具有相同的分析器,加上 first.edge
并且last.edge
都使用edge_ngram
分析器,则此查询:
GET /_search
{
"query": {
"multi_match" : {
"query": "Jon",
"type": "cross_fields",
"fields": [
"first", "first.edge",
"last", "last.edge"
]
}
}
}
将被执行为:
blended("jon", fields: [first, last])
| (
blended("j", fields: [first.edge, last.edge])
blended("jo", fields: [first.edge, last.edge])
blended("jon", fields: [first.edge, last.edge])
)
换句话说,first
andlast
将被组合在一起并作为单个字段处理,并且first.edge
和last.edge
将被组合在一起并作为单个字段处理。
有多个组是好的,但是当联合operator
或者 minimum_should_match
,它可以从遭受同样的问题, 如most_fields
或best_fields
。
您可以自己轻松地将此查询重写为两个单独的cross_fields
查询与一个dis_max
查询的组合,并将minimum_should_match
参数仅应用于其中一个:
GET /_search
{
"query": {
"dis_max": {
"queries": [
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first", "last" ],
"minimum_should_match": "50%" # 1
}
},
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "*.edge" ]
}
}
]
}
}
}
1 | 任一will 或smith 必须在任一的存在first 或last 字段 |
---|---|
您可以通过analyzer
在查询中指定参数来强制所有字段进入同一组。
GET /_search
{
"query": {
"multi_match" : {
"query": "Jon",
"type": "cross_fields",
"analyzer": "standard", # 1
"fields": [ "first", "last", "*.edge" ]
}
}
}
1 | standard 对所有字段使用分析器。 |
---|---|
这将被执行为:
blended("will", fields: [first, first.edge, last.edge, last])
blended("smith", fields: [first, first.edge, last.edge, last])
5.bool_prefix
类型
该bool_prefix
类型的评分行为类似于most_fields
,但使用 match_bool_prefix
查询而不是 match
查询。
GET /_search
{
"query": {
"multi_match" : {
"query": "quick brown f",
"type": "bool_prefix",
"fields": [ "subject", "message" ]
}
}
}
analyzer
,boost
,operator
,minimum_should_match
,lenient
, zero_terms_query
,和auto_generate_synonyms_phrase_query
在解释的参数匹配查询的支持。的 fuzziness
,prefix_length
,max_expansions
,fuzzy_rewrite
,和 fuzzy_transpositions
参数都支持了用于构建长期的查询条件,但没有对前缀查询从最终期限结构的影响。
在slop
和cutoff_frequency
参数不受此查询类型的支持。
tie_breaker
参数
默认情况下,每个 per-termblended
查询将使用组中任何字段返回的最佳分数。然后在跨组组合分数时,查询使用任何组中的最佳分数。该tie_breaker
参数可以更改这两个步骤的行为:
0.0 | 从(例如)first_name:will 和last_name:will (默认)中 取出单个最佳分数 |
---|---|
1.0 | 加起来的分数等于(eg):first_name:will 和 last_name:will |
0.0 < n < 1.0 | 取单个最佳分数 +( tie_breaker * 其他匹配字段/组的每个分数 ) |
-
重要
-
cross_fields
和fuzziness
-
该
fuzziness
参数不能与cross_fields
类型一起使用。
-
3.8 常用词查询
7.3.0中弃用
3.9 查询字符串(Query string)
使用具有严格语法的解析器根据提供的查询字符串返回文档。
此查询使用语法根据运算符(例如AND
or NOT
)来解析和拆分提供的查询字符串。然后,查询在返回匹配文档之前独立分析每个拆分文本。
您可以使用query_string
查询来创建包含通配符、跨多个字段的搜索等的复杂搜索。虽然用途广泛,但查询是严格的,如果查询字符串包含任何无效语法,则返回错误。
-
警告
-
因为它会针对任何无效语法返回错误,所以我们不建议
query_string
对搜索框使用查询。 -
如果您不需要支持查询语法,请考虑使用
match
查询。如果您需要查询语法的功能,请使用simple_query_string
不那么严格的查询。
-
示例请求
运行以下搜索时,query_string
查询分为(new york city) OR (big apple)
两部分:new york city
和big apple
。该 content
字段的分析器然后在返回匹配文档之前独立地将每个部分转换为标记。因为查询语法不使用空格作为运算符,new york city
所以按原样传递给分析器。
GET /_search
{
"query": {
"query_string": {
"query": "(new york city) OR (big apple)",
"default_field": "content"
}
}
}
参数
-
query
(必需,字符串)您希望解析并用于搜索的查询字符串。请参阅 查询字符串语法。
-
default_field
(可选,字符串)如果查询字符串中未提供任何字段,则您希望搜索的默认字段。默认为
index.query.default_field
索引设置,其默认值为*
。该*
值提取所有符合术语查询条件的字段并过滤元数据字段。如果没有prefix
指定,所有提取的字段然后被组合以构建查询。搜索所有符合条件的字段不包括嵌套文档。使用nested
查询来搜索这些文档。对于具有大量字段的映射,搜索所有符合条件的字段可能会很昂贵。一次可以查询的字段数是有限制的。它由indices.query.bool.max_clause_count
搜索设置定义,默认为 1024。 -
allow_leading_wildcard
(可选,布尔值)如果
true
,通配符*
和?
允许作为查询字符串的第一个字符。默认为true
. -
analyze_wildcard
(可选,布尔值)如果
true
,则查询尝试分析查询字符串中的通配符术语。默认为false
. -
analyzer
(可选,字符串)分析器用于将查询字符串中的文本转换为标记。默认为为映射 的 索引时间分析器
default_field
。如果没有映射分析器,则使用索引的默认分析器。 -
auto_generate_synonyms_phrase_query
(可选,布尔值)如果
true
, 则为多术语同义词自动创建匹配短语查询。默认为true
. 有关示例,请参阅同义词和query_string
查询。 -
boost
(可选,浮点数)用于减少或增加查询相关性分数的浮点数 。默认为
1.0
.Boost 值相对于 的默认值1.0
。0
和之间的提升值会1.0
降低相关性分数。大于 的值会1.0
增加相关性分数。 -
default_operator
(可选,字符串)如果未指定运算符,则用于解释查询字符串中的文本的默认布尔逻辑。有效值为:
OR
(默认)例如,查询字符串capital of Hungary
被解释为capital OR of OR Hungary
。AND
例如,查询字符串capital of Hungary
被解释为capital AND of AND Hungary
。 -
enable_position_increments
(可选,布尔值)如果
true
,在从query_string
搜索构造的查询中启用位置增量。默认为true
. -
fields
(可选,字符串数组)要搜索的字段数组。您可以使用此参数查询来跨多个字段进行搜索。请参阅 搜索多个字段。
-
fuzziness
(可选,字符串)模糊匹配允许的最大编辑距离。有关模糊语法,请参阅Fuzziness。
-
fuzzy_max_expansions
(可选,整数)查询扩展到模糊匹配的最大术语数。默认为
50
. -
fuzzy_prefix_length
(可选,整数)用于模糊匹配的起始字符数保持不变。默认为
0
. -
fuzzy_transpositions
(可选,布尔值)如果
true
,模糊匹配的编辑包括两个相邻字符的换位(ab → ba)。默认为true
. -
lenient
(可选,布尔值)如果,则忽略
true
基于格式的错误,例如为数字字段提供文本值。默认为false
. -
max_determinized_states
(可选,整数) 查询所需的最大自动机状态数 。默认为
10000
。Elasticsearch 在内部使用Apache Lucene来解析正则表达式。Lucene 将每个正则表达式转换为包含多个确定状态的有限自动机。您可以使用此参数来防止该转换无意中消耗过多资源。您可能需要增加此限制才能运行复杂的正则表达式。 -
minimum_should_match
(可选,字符串)必须与要返回的文档匹配的最小子句数。有关有效值和更多信息,请参阅
minimum_should_match
参数。请参阅 如何minimum_should_match
工作的一个例子。 -
quote_analyzer
(可选,字符串)分析器用于将查询字符串中的引用文本转换为标记。默认为
search_quote_analyzer
映射的default_field
.对于带引号的文本,此参数会覆盖参数中指定的分析器analyzer
。 -
phrase_slop
(可选,整数)短语匹配标记之间允许的最大位置数。默认为
0
. 如果0
,则需要精确的短语匹配。转置项的斜率为2
。 -
quote_field_suffix
(可选,字符串)附加到查询字符串中引用文本的后缀。您可以使用此后缀对完全匹配使用不同的分析方法。请参阅将精确搜索与词干混合。
-
rewrite
(可选,字符串)用于重写查询的方法。有关有效值和更多信息,请参阅
rewrite
参数。 -
time_zone
(可选,字符串) 用于将查询字符串中的值转换为 UTC 的协调世界时 (UTC) 偏移量或 IANA 时区
date
。有效值为 ISO 8601 UTC 偏移量,例如+01:00
or -08:00
和 IANA 时区 ID,例如America/Los_Angeles
。
笔记
查询字符串语法
查询字符串“mini-language”由 查询字符串和API 中的 q
查询字符串参数search
使用。
查询字符串被解析为一系列术语和运算符。一个词可以是一个词—— 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.title
,book.content
或book.date
包含quick
或brown
(注意我们需要如何*
用反斜杠转义):book.\*:(quick OR brown)
-
其中该字段
title
具有任何非空值:_exists_:title
通配符
通配符搜索可以在单个术语上运行,?
用于替换单个字符,以及*
替换零个或多个字符:
qu?ck bro*
请注意,通配符查询会占用大量内存并且性能非常差——想想需要查询多少个词来匹配查询字符串"a* b* c*"
。
-
警告
-
纯通配符
\*
被重写为exists
查询以提高效率。因此,通配符"field:*"
将匹配具有空值的文档,如下所示:
-
{ "field": "" }
-
...如果该字段丢失或设置为显式空值,则不匹配,如下所示:
-
{ "field": null }
-
-
警告
-
允许在单词的开头使用通配符(例如
"*ing"
)特别重要,因为需要检查索引中的所有术语,以防它们匹配。可以通过设置allow_leading_wildcard
为禁用前导通配符false
。
-
仅应用在角色级别操作的部分分析链。因此,例如,如果分析器同时执行小写和词干提取,则只会应用小写:对缺少某些字母的单词执行词干提取是错误的。
通过设置analyze_wildcard
为 true,*
将分析以 a 结尾的查询,并通过确保前 N-1 个标记的精确匹配和最后一个标记的前缀匹配,从不同的标记构建一个布尔查询。
常用表达
正则表达式模式可以通过将它们包装在正斜杠 ( "/"
) 中来嵌入到查询字符串中:
姓名:/joh?n(ath[oa]n)/
正则表达式语法中解释了支持的正则表达式语法。
该allow_leading_wildcard
参数对正则表达式没有任何控制权。如下查询字符串将强制 Elasticsearch 访问索引中的每个术语:
/.*n/
谨慎使用!
模糊性
您可以使用运算符~
运行fuzzy
queries:
quikc~brwn~foks~
对于这些查询,查询字符串是规范化的。如果存在,则仅应用分析器中的某些过滤器。有关适用过滤器的列表,请参阅Normalizers。
该查询使用 Damerau-Levenshtein 距离 来查找最多有两个变化的所有术语,其中变化是单个字符的插入、删除或替换,或两个相邻字符的换位。
默认编辑距离为2
,但编辑距离1
应该足以捕获 80% 的所有人类拼写错误。它可以指定为:
quikc~1
-
警告
邻近搜索
虽然短语查询(例如"john smith"
)期望所有术语的顺序完全相同,但邻近查询允许指定的单词相距更远或以不同的顺序排列。与模糊查询可以指定单词中字符的最大编辑距离相同,邻近搜索允许我们指定短语中单词的最大编辑距离:
"fox quick"~5
字段中的文本与查询字符串中指定的原始顺序越接近,则认为该文档越相关。与上面的示例查询相比,该短语"quick fox"
将被认为比 更相关"quick brown fox"
。
范围
可以为日期、数字或字符串字段指定范围。包含范围用方括号指定,[min TO max]
不包含范围用大括号指定{min TO max}
。
-
2012年的所有日子:
date:[2012-01-01 TO 2012-12-31]
-
数字 1..5
count:[1 TO 5]
-
alpha
和之间的标签omega
,不包括alpha
和omega
:tag:{alpha TO omega}
-
10以上的数字
count:[10 TO *]
-
2012 年之前的日期
date:{* TO 2012-01-01}
大括号和方括号可以组合使用:
-
从 1 到但不包括 5 的数字
count:[1 TO 5}
一侧无界的范围可以使用以下语法:
age:>10
age:>=10
age:<10
age:<=10
-
提示
-
要将上限和下限与简化语法结合起来,您需要使用
AND
运算符连接两个子句: -
age:(>=10 AND <20) age:(+>=10 +<20)
-
查询字符串中范围的解析可能很复杂且容易出错。使用显式range
查询要可靠得多。
提升
使用boost运算符^
使一个术语比另一个更相关。例如,如果我们想查找有关狐狸的所有文档,但我们对快狐狸特别感兴趣:
quick^2 fox
默认boost
值为 1,但可以是任何正浮点数。0 到 1 之间的提升会降低相关性。
Boosts 也可以应用于短语或组:
"john smith"^2 (foo bar)^4
布尔运算符
默认情况下,所有术语都是可选的,只要一个术语匹配即可。一搜索foo bar baz
就会发现,包含一个或多个的任何文件 foo
或bar
或baz
。我们已经讨论了default_operator
上面的内容,它允许您强制要求所有术语,但也可以在查询字符串本身中使用布尔运算符以提供更多控制。
首选运算符是+
(该术语必须存在)和-
(该术语不得存在)。所有其他条款都是可选的。例如,这个查询:
quick brown +fox -news
指出:
-
fox
必须在场 -
news
不得在场 -
quick
并且brown
是可选的——它们的存在增加了相关性
熟悉的布尔运算符AND
, OR
and NOT
(也写成&&
, ||
and !
)也受支持,但要注意它们不遵守通常的优先规则,所以当多个运算符一起使用时应该使用括号。例如,前面的查询可以改写为:
-
((quick AND fox) OR (brown AND fox) OR fox) AND NOT news
这种形式现在正确地复制了原始查询的逻辑,但相关性评分与原始查询几乎没有相似之处。
{
"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 /my-index-000001/_search
{
"query" : {
"query_string" : {
"query" : "kimchy\\!",
"fields" : ["user.id"]
}
}
}
保留字符是: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
未能正确转义这些特殊字符可能会导致语法错误,从而阻止您的查询运行。
-
提示
-
<
并且>
根本无法逃脱。阻止它们尝试创建范围查询的唯一方法是将它们从查询字符串中完全删除。
-
空格和空查询
空格不被视为运算符。
如果查询字符串为空或仅包含空格,则查询将产生一个空结果集。
避免query_string
对嵌套文档使用查询
query_string
搜索不返回嵌套文档。要搜索嵌套文档,请使用nested
query。
搜索多个字段
您可以使用该fields
参数query_string
跨多个字段执行搜索。
query_string
针对多个字段运行查询的想法是将每个查询词扩展为一个 OR 子句,如下所示:
field1:query_term 或 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)"
}
}
}
由于多个查询是从单个搜索词生成的,因此使用dis_max
带有tie_breaker
. 例如(name
使用^5
符号增加 5 ):
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name^5"],
"query" : "this AND that OR thus",
"tie_breaker" : 0
}
}
}
简单的通配符也可用于搜索文档的“内部”特定内部元素。例如,如果我们有一个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)"
}
}
}
-
提示
-
由于
\
(backslash) 是 json 字符串中的特殊字符,需要对其进行转义,因此上面的query_string
.
-
fields 参数还可以包括基于模式的字段名称,允许自动扩展到相关字段(包括动态引入的字段)。例如:
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name.*^5"],
"query" : "this AND that OR thus"
}
}
}
多字段搜索的附加参数
query_string
对多个字段运行查询时,支持以下附加参数。
-
type
(可选,字符串)确定查询如何匹配和评分文档。有效值为:
-
best_fields
(默认)查找匹配任何字段并使用
_score
任何匹配字段中最高值的文档 。见best_fields
。
-
bool_prefix
match_bool_prefix
在每个字段上 创建一个查询并组合_score
来自每个字段的 。见bool_prefix
。
-
cross_fields
像对待
analyzer
一个大字段一样对待字段。在任何字段中查找每个单词。见cross_fields
。
-
most_fields
查找与任何字段匹配的文档并组合
_score
来自每个字段的 。见most_fields
。
-
phrase
match_phrase
对每个字段 运行查询并使用_score
来自最佳字段的查询。见phrase
和phrase_prefix
。
-
phrase_prefix
match_phrase_prefix
对每个字段 运行查询并使用_score
来自最佳字段的查询。见phrase
和phrase_prefix
。
-
注意:
multi_match
根据该type
值,可能会提供其他顶级参数 。
-
同义词和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
匹配带有 termny
或连词的文档new AND york
。默认情况下,该参数auto_generate_synonyms_phrase_query
设置为true
。
minimum_should_match
如何工作
该query_string
拆分各地各运营商查询,以创建整个输入一个布尔查询。您可以使用minimum_should_match
来控制结果查询中应该匹配多少个“应该”子句。
GET /_search
{
"query": {
"query_string" : {
"default_field": "title",
"query" : "ny city",
"auto_generate_synonyms_phrase_query" : false
}
}
}
上面的例子创建了一个布尔查询:
(title:this title:that title:thus)~2
匹配至少有两个方面的文件this
,that
或thus
在单场title
。
如何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))
匹配字段title
和 上 具有析取最大值的文档content
。此处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
匹配具有三个“应该”子句中至少两个的文档,每个子句都由每个术语的字段上的析取最大值组成。
如何minimum_should_match
可以跨场搜索
字段中的cross_fields
值type
表示在分析输入时将具有相同分析器的字段组合在一起。
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
匹配具有三个 perterm 混合查询中至少两个的文档。
允许昂贵的查询
查询字符串查询可以在内部转换为 aprefix query
这意味着如果前缀查询被禁用,如解释here查询将不会被执行,并将抛出异常。
3.10 简单查询字符
使用具有有限但容错语法的解析器,根据提供的查询字符串返回文档。
此查询使用简单的语法来解析和拆分提供的查询字符串,并将其拆分为基于特殊运算符的术语。查询然后在返回匹配文档之前独立分析每个术语。
虽然它的语法比query_string
query更受限制 ,但simple_query_string
查询不会为无效语法返回错误。相反,它会忽略查询字符串的任何无效部分。
示例请求
GET /_search
{
"query": {
"simple_query_string" : {
"query": "\"fried eggs\" +(eggplant | potato) -frittata",
"fields": ["title^5", "body"],
"default_operator": "and"
}
}
}
参数
-
query
(必需,字符串)您希望解析并用于搜索的查询字符串。请参阅简单查询字符串语法。
-
fields
(可选,字符串数组)要搜索的字段数组。此字段接受通配符表达式。您还可以使用插入符号 (
^
) 表示法提高与特定字段匹配的相关性分数。见 通配符和每场提升的fields
参数的例子。默认为index.query.default_field
索引设置,其默认值为*
。该*
值提取所有符合术语查询条件的字段并过滤元数据字段。如果没有prefix
指定,所有提取的字段然后被组合以构建查询。-
警告
一次可以查询的字段数是有限制的。它由
indices.query.bool.max_clause_count
搜索设置定义,默认为1024
.
-
-
default_operator
(可选,字符串)如果未指定运算符,则用于解释查询字符串中的文本的默认布尔逻辑。有效值为:
-
OR
(默认)例如,查询字符串capital of Hungary
被解释为capital OR of OR Hungary
。
-
AND
例如,查询字符串capital of Hungary
被解释为capital AND of AND Hungary
。
-
-
all_fields
[ 6.0.0 ] 在 6.0.0 中已弃用。设置
fields
以*
代替(可选,布尔值)如果true
,搜索索引字段映射中的所有可搜索字段。 -
analyze_wildcard
(可选,布尔值)如果
true
,则查询尝试分析查询字符串中的通配符术语。默认为false
. -
analyzer
(可选,字符串)分析器用于将查询字符串中的文本转换为标记。默认为为映射 的 索引时间分析器
default_field
。如果没有映射分析器,则使用索引的默认分析器。 -
auto_generate_synonyms_phrase_query
(可选,布尔值)如果
true
,解析器match_phrase
为每个多位置标记创建一个 查询 。默认为true
. 例如,请参阅多位置令牌。 -
flags
-
fuzzy_max_expansions
(可选,整数)查询扩展到模糊匹配的最大术语数。默认为
50
. -
fuzzy_prefix_length
(可选,整数)用于模糊匹配的起始字符数保持不变。默认为
0
. -
fuzzy_transpositions
(可选,布尔值)如果
true
,模糊匹配的编辑包括两个相邻字符的换位(ab → ba)。默认为true
. -
lenient
(可选,布尔值)如果,则忽略
true
基于格式的错误,例如为数字字段提供文本值。默认为false
. -
minimum_should_match
(可选,字符串)必须与要返回的文档匹配的最小子句数。有关有效值和更多信息,请参阅
minimum_should_match
参数。 -
quote_field_suffix
(可选,字符串)附加到查询字符串中引用文本的后缀。您可以使用此后缀对完全匹配使用不同的分析方法。请参阅将精确搜索与词干混合。
笔记
简单的查询字符串语法
该simple_query_string
查询支持以下运算符:
-
+
表示 AND 运算 -
|
表示 OR 操作 -
-
否定单个令牌 -
"
包装许多标记以表示用于搜索的短语 -
*
在术语的末尾表示前缀查询 -
(
and)
表示优先 -
~N
词后表示编辑距离(模糊性) -
~N
短语后面表示slop数量
要从字面上使用这些字符之一,请使用前面的反斜杠 ( \
)对其进行转义。
这些运算符的行为可能因default_operator
值而异。例如:
GET /_search
{
"query": {
"simple_query_string": {
"fields": [ "content" ],
"query": "foo bar -baz"
}
}
}
该搜索的目的是只包含返回文档foo
或bar
也做不包含baz
。但是,由于 a default_operator
of OR
,此搜索实际上返回包含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"
}
}
}
有效值
可用的标志是:
-
ALL
(默认)启用所有可选运算符。
-
AND
启用
+
AND 运算符。 -
ESCAPE
\
作为转义字符 启用。 -
FUZZY
~N
在单词后 启用运算符,其中N
是表示允许的匹配编辑距离的整数。参见模糊性。 -
NEAR
在匹配标记之间允许的最大位置数的
~N
短语之后 启用运算符N
。同义SLOP
。 -
NONE
禁用所有运算符。
-
NOT
启用
-
NOT 运算符。 -
OR
启用
\|
OR 运算符。 -
PHRASE
启用
"
用于搜索短语的引号运算符。 -
PRECEDENCE
使
(
和)
运算符能够控制运算符优先级。 -
PREFIX
启用
*
前缀运算符。 -
SLOP
在匹配标记之间允许的最大位置数的
~N
短语之后 启用运算符N
。同义NEAR
。 -
WHITESPACE
启用空格作为拆分字符。
通配符和每场提升的fields
参数
可以使用通配符指定字段,例如:
GET /_search
{
"query": {
"simple_query_string" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ] # 1
}
}
}
1 | 查询title ,first_name 和last_name 字段。 |
---|---|
可以使用脱字符 ( ^
) 表示法提升单个字段:
GET /_search
{
"query": {
"simple_query_string" : {
"query" : "this is a test",
"fields" : [ "subject^3", "message" ] # 1
}
}
}
1 | 该subject 场是三倍的重要message 领域。 |
---|---|
多位置令牌
默认情况下,simple_query_string
查询解析器match_phrase
为查询字符串中的每个多位置标记创建一个 查询 。例如,解析器match_phrase
为多词同义词创建查询ny, new york
:
(ny OR ("new york"))
要将多位置标记与AND
连词匹配,请设置 auto_generate_synonyms_phrase_query
为false
:
GET /_search
{
"query": {
"simple_query_string": {
"query": "ny city",
"auto_generate_synonyms_phrase_query": false
}
}
}
对于上面的示例,解析器创建以下 bool
查询:
(ny OR (new AND york)) city)
此bool
查询匹配具有 termny
或连接词的 文档new AND york
。