原文链接:https://xiets.blog.csdn.net/article/details/132348920
版权声明:原创文章禁止转载
专栏目录:Elasticsearch 专栏(总目录)
ES 搜索 API 官网文档:Search APIs
先创建一个索引,并写入一些文档用于搜索示例:
写入一些文档示例:
官网API:The option
搜索结果中的文档数据封装在响应的 字段中,搜索时可以只返回指定文档字段,请求格式:
返回部分字段搜索示例:
官网API:Count API
如果搜索数据匹配的结果非常多,需要使用分页返回结果,需要告诉客户端结果文档的总数。ES 的 API 可以查询搜索匹配的文档总数量。
API 请求格式:
官网API:Paginate search results
使用分页搜索,需要告诉 ES 从匹配的文档列表中的第几个文档开始返回,以及最多要返回多少个文档,搜索参数 和 就是分别表示开始返回的文档位置和数量,from 默认值为 0,size 默认值为 10。
分页搜索 请求格式:
结果计数与分页请求示例:
使用 ES 执行一个搜索请求,如果查询条件非常复杂,搜索请求可能响应比较慢。ES 提供了 profile 功能,可以详细列出执行一个搜索请求的细节,以及每一个步骤的耗时,可以帮助用户对查询条件进行性能分析,以便优化查询条件。
启用 profile 功能,只需要在搜索请求中增加 的参数:
性能分析搜索请求示例:
执行上面的搜索请求后,将返回一段冗长的信息。除了在 节点返回匹配的文档外,主要还返回了一个 节点,该节点详细记录了搜索的过程。从下面的返回信息中可以看出,全文搜索 “龙门”,拆分成了两个子搜索 “name:龙 name:门”,并给出了子搜索结果的详细信息。
完整的搜索响应:
官网API:Explain API
当执行搜索请求搜索文档时,搜索引擎会对匹配的文档打分,如果没有指定排序规则,ES 将使用默认的打分算法对文档排序。有时我们需要知道指定搜索条件对某个文档具体的打分详情(包括不匹配时的详情),以便对搜索条件进行优化。ES 提供了 API 可以查看搜索时的匹配详情。
API 请求格式,查询「指定搜索条件」对「某个具体文档」的匹配详情:
API 请求示例:
搜索请求的通用格式:
官网API:Match all query
查询用于遍历文档(即查询所有文档)。ES 使用 match_all 查询时,不对文档打分(默认所有文档都满分匹配)。查询所有文档通常需要和分页查询一起使用。
match_all 查询请求格式:
match_all 查询请求示例:
官网API:Term-level queries
ES 针对不同的数据类型提供了丰富的搜索匹配功能,主要包括用于精准匹配的 Term 查询,以及用于分词匹配的 match 查询。
Term 级别查询的类型:
- 、、:等值匹配(全匹配)。
- :数值/日期范围匹配。
- :文档字段是否存在指定字段,存在则返回。
- :根据ID查询文档。
- :匹配文档字段值的前缀。
- :正则表达式匹配。
- :模糊查询(编辑距离查询)。
- :通配符模式匹配。
其中 、、、 属于 慢查询,如果 设置为 false,将不会执行慢查询。
官网API:
- Term query
- Terms query
- Terms set query。
查询用于等值匹配查询(全匹配查询),term 匹配的字段类型支持 数值型、布尔型、日期时间、关键字类型 (包括这些类型的数组类型)。 查询则是 term 的扩展形式,用于同时查询一个或多个值(多个值之间是逻辑或的关系)。 查询与 terms 相似,terms_set 表示最少需要匹配给定查询值中的指定数量。
、 和 查询的请求格式:
查询请求示例:
查询请求示例:
查询请求示例:
官网API:Range query
查询用于范围匹配,一般只用于 数值类型 和 日期类型 等可比较大小的字段类型的查询。
range 查询需要指定查询的字段值边界,有以下请求参数用于指定范围边界:
- :大于;
- :大于等于;
- :小于;
- :小于等于。
查询请求格式:
查询请求示例:
官网API:Exists query
ES 写入文档时,可以只写入部分字段,或者某个字段写入 null 值。而 查询就是用于查询某个字段是否存在。
字段存在(满足匹配)的条件有:
- 值存在且不为;
- 值是数组,但不是空数组,并且数组元素不全为。
查询请求格式:
查询请求示例:
官网API:IDs
查询直接通过文档ID查询文档,查询格式:
查询示例:
官网API:Prefix query
查询用于查询指定字段中包含特定前缀的文档,前缀查询只能用于查询 关键字(keyword)、文本(text) 和 通配符(wildcard) 类型的字段。
查询属于 慢查询,可以使用 映射参数加快前缀查询速度。
如果禁用了慢查询( 设置为了 false),则不会执行 查询。但如果启用了 ,则会构建一个优化的查询,该查询将不被认为是慢查询。
查询格式:
查询示例:
官网API:Regexp query
查询将使用正则表达式来匹配文档字段值。 查询只能用于查询 关键字(keyword) 和 文本(text) 类型的字段。
查询属于 慢查询,如果禁用了慢查询( 设置为了 false),则不会执行 查询。
查询格式:
查询示例:
官网API:Fuzzy query
查询属于模糊查询,用于搜索与搜索词相似的词的文档,相似的衡量标准使用的编辑距离为 莱文斯坦距离。
编辑距离是将一个词语变成另一词语所需的单个字符更改的次数,这里的更改包括:
- 改变一个字符:box -> fox
- 删除一个字符:black -> lack
- 添加一个字符:sic -> sick
- 交换两个字符:act -> cat
其中上面的每一个更改动作都表示一个编辑距离,例如将 hex 变为 hi,可以经过删掉一个字符x(hex -> he),然后把 e 改为 i(he -> hi),这就表示将 hex 变为 hi 需要经过 2 个编辑距离。
查询只能用于查询 关键字(keyword) 和 文本(text) 类型的字段。
查询属于 慢查询,如果禁用了慢查询( 设置为了 false),则不会执行 查询。
查询格式:
最大编辑距离 的值参考:Fuzziness
查询示例:
官网API:Wildcard query
通配符查询返回与通配符搜索词匹配的文档。 用于匹配零个或多个字符, 用于匹配单个字符。 查询只能用于查询 关键字(keyword)、文本(text) 和 通配符(wildcard) 类型的字段。
查询属于 慢查询,如果禁用了慢查询( 设置为了 false),则不会执行 查询。
查询格式:
查询示例:
官网API:Boolean query
布尔查询是一种复合查询,可以根据多个普通的子查询使用逻辑与或非组合出满足各种复杂条件的查询。一个布尔查询包含了多个子查询,每一个子查询的结果都是一个布尔值,而多个子查询的结果再根据逻辑与或非的关系又组合成最终的一个布尔值用于最终确定是否匹配文档。布尔查询对文档的打分是按各子查询的匹配程度对文档就行综合打分。
布尔查询中多个子查询结果支持的逻辑组合方式:
- :逻辑与,必须匹配所有查询条件;
- :逻辑或,至少匹配其中一个查询条件;
- :逻辑非,必须不匹配所有查询条件;
- :逻辑与,必须匹配所有查询条件,但该条件的匹配程度不参与打分计算(相当于不参与打分的)。
查询请求格式:
bool 查询的 must 查询示例:
bool 查询的 should 查询示例:
bool 查询的 must_not 查询示例:
bool 查询的 filter 查询示例:
官网API:Full text queries
全文搜索一般指对 文本(text)类型数据 的搜索。与 term、range 等全匹配的结构化搜索不同,全文搜索可以部分匹配。全文搜索首先对搜索词进行分析(分词),根据分析结果再构建出多个子查询。
全文搜索包含 、、、 和 等查询方式。
官网API:Match query
查询是全文搜索的主要方式。
查询请求格式:
查询请求示例:
官网API:Multi-match query
是 查询的多字段版本。 查询可以使用同一个查询关键词同时查询多个 text 类型的字段(只要其中一个字段有匹配的即可),相当于使用 bool 查询的 should 查询封装了两个 match 子查询。
查询请求格式:
搜索示例中只有一个字段是 text 类型,这里不做示例。
官网API:Match phrase query
查询用于匹配切确的短语或临近的词语,也就是希望不分词,或者分词后中间最多只能间隔指定字数的距离。
查询请求格式:
查询请求示例:
查询请求示例(临近的词语):
官网API:Query string query
查询使用严格的解析器解析查询字符串,并根据解析的结果逻辑查询文档。
查询使用查询语法(Query string syntax)来解析和分割基于运算符的查询字符串,例如 和 。在执行搜索之前将独立分析每一个分割的文本(Text analysis)。
使用 查询可以创建复杂的搜索逻辑,其中包括 通配符、跨多个字段、与或非逻辑关系 等搜索。 查询是语法严格的,如果查询字符串包含任何无效的语法,将返回错误。
注意:由于任何无效的语法都会返回错误,因此不建议使用 查询。如果不需要支持查询语法,应考虑 查询。如果需要查询语法功能,可以使用对语法不太严格的 查询。
查询格式:
查询示例:
上述查询将搜查 字段中匹配(match) 或 的文档。
查询中的 查询字符串,使用一套称为“mini-language”的语法。该语法也适用于使用 请求来执行搜索的 查询参数。
后面将介绍 查询字符串支持的各种语法操作。
查询字符串的逻辑运算,支持 、、 逻辑运算(可以使用 、、 代替),并且支持使用 括号分组。
上面的搜索请求表示查询索引文档的 字段,需要匹配(match) 或者 ,并且不是 。
后面为简单演示,只展示 查询字符串的值。
查询中,如果没有在 查询字符串中指明要查询的字段,则默认查询 指定的字段,或者查询 指定的多个字段。
查询也可以直接在 查询字符串中指明要查询的字段,语法格式:
查询字符串取值的各种语法格式:
查询字符串的字段取值也支持通配符,表示一个字符,表示0个或多个字符。
通配符查询语法示例:
注意:通配符查询可能会使用大量内存并且性能非常糟糕。为了提高效率,纯通配符 的查询将被重写为 查询。
查询字符串的使用 包括起来表示使用正则表达式匹配,例如:
模糊查询使用 运算符:
上面的查询使用 Damerau-Levenshtein distance 编辑距离查找最多 2 次更改的所有查询分词。其中单个字符的插入、删除、替换,或者两个相邻字符的调换,称为 1 次更改(编辑距离为1)。
默认的编辑距离为 ,但编辑距离 应该足以捕获 80% 的所有人类的拼写错误,可以指定为:。
注意:避免将模糊查询与通配符混合在一起。
不支持混合使用模糊和通配符运算符 。混合时,不应用其中一种运算符。例如,你可以搜索 (模糊) 或 (通配符),但 搜索不会应用模糊操作符()。
虽然短语查询(例如)期望所有分词的顺序完全相同,但邻近查询允许指定的分词相距较远或采用不同的顺序。就像模糊查询可以指定分词中字符的最大编辑距离一样,邻近搜索允许我们指定短语中分词的最大编辑距离:
上面的查询表示 和 之间最多只能有 5 个单词。字段中的文本与查询字符串中指定的原始顺序越接近,该文档就越相关。与上面的示例查询相比,文本字段值中的 将被认为比 更相关。
查询字符串可以为 日期、数字、字符串 字段指定查询值范围。范围使用中括号和大括号表示:
- 闭区间范围:
- 开区间范围:
- 半开区间范围:、
范围取值示例:
如果是单边无界,可以使用以下语法:
还可以使用 和 运算符组合:
- 或
使用 运算符,可以提升某个查询词匹配的相关性。
例如查询 ,表示查询 和 ,但 的相关性()需提升为 ,也就是 的匹配分数较高。
相关性 是一个正浮点数,默认值为 。 之间的提升会降低相关性。
相关性提升也可以用在短语或组:、
搜索字段,默认情况下只需要匹配其中一个分词即可(使用 和 自主控制的除外),可以使用 和 运算符组合出 必选匹配 和 必须不匹配 的逻辑:
上面查询 content 字段的语法含义:
- 和 可选。
- 必须匹配。
- 必须不匹配。
使用 布尔查询() 也可以达到相同效果:
多个查询词或子句可以使用括号组合在一起形成子查询:
组可用于定位特定字段,或提升子查询的结果:
的查询语法会使用一些特殊字符用作运算符,这些字符称为保留字符。
保留字符有:
如果要把保留字符当做普通的字符串搜索,需要在前面加上 转义。例如,搜索 ,需要将查询编写为 。
空格不被视为运算符。
如果查询字符串为空或仅包含空格,则查询将产生空结果集。
查询可以使用 参数实现跨多个字段查询。
针对使用 查询多个字段的想法是将每个查询项扩展为 子句,如下所示:
多字段查询示例:
由于多个查询是根据各个搜索词生成的,因此可以使用带有 的 查询自动将它们组合起来。例如使用提升相关性操作符 将 字段的相关性提示为 :
可以通过简单的通配符()搜索某个字段的所有子字段:
参数中的通配符()匹配的字段也可以使用 提升相关性:
官网API:Simple query string query
使用简单语法但有容错的解析器解析查询字符串。
此查询使用 简单的语法 来解析提供的查询字符串()并将其分割为基于特殊运算符的词语。然后查询文档并在返回匹配文档之前独立分析每个词语。
虽然 查询语法丰富并严格,但 查询不会因语法无效而返回错误。相反,它会忽略查询字符串的任何无效部分。
查询格式:
支持的查询语法(运算符):
- 表示 AND 运算。
- 表示 OR 运算。
- 表示 NOT 运算符,否定单个标记。
- 包含多个标记来表示要搜索的短语(需要不分割/连续匹配的短语)。
- 在词语末尾表示前缀查询(通配符查询)。
- 和 表示优先级(分组)。
- 放在词语后面,表示编辑距离(模糊查询)。
- 短语后在表示溢出量。
要按字面意思使用这些字符,需要使用前反斜杠()将其转义。这些运算符的行为可能会根据 参数值的不同而有所不同。
参数的枚举值,多个值之间使用分割(如: ):
- :(默认)启用所有可选运算符。
- :启用 AND 运算符。
- : 作为转义字符启用。
- : 在词语后启用运算符,其中 是表示允许匹配的编辑距离的整数。请参阅模糊性。
- : 在短语之后启用运算符,其中 是匹配标记之间允许的最大位置数。同义于 。
- :禁用所有运算符。
- :启用 NOT 运算符。
- :启用 OR 运算符。
- :启用 用于搜索短语的引号运算符。
- :启用 和 运算符来控制运算符优先级。
- :启用 前缀运算符。
- : 在短语后面启用运算符,其中 是匹配标记之间允许的最大位置数。同义于 。
- :启用空格作为分割字符。
查询示例:
官网API:Geo-distance query
ES 支持地理位置坐标和形状区域数据类型的存储和搜索。其中地理坐标存储了经纬度,可以根据位置距离搜索数据。
类型表示地理坐标类型,地理类型官网相关链接:
- Geopoint field type:地理坐标类型。
- Geoshape field type:地理形状类型。
对于 类型的字段,有 3 种查询方式,分别为 查询、查询 和 查询。
其中 查询是根据指定中心坐标点,查询指定距离范围内的文档。
查询请求格式:
查询请求示例,搜索 2km 内的酒店:
官网API:Suggesters
搜索建议指的是用户在输入搜索词的过程中,系统根据已输入部分给出建议的搜索关键词,也就是自动补全,用户只需要点击其中一个搜索关键词直接进行搜索。要实现搜索建议,需要在搜索过程中,用户每输入一个字,就把已输入部分发到服务端查询匹配的搜索建议词列表,因此该场景需要服务端能快速响应请求。通过给出搜索建议,可以避免用户输入错误的关键词,或者引导用户使用更合适的关键词搜索,可以大大提升用户搜索体验和搜索结果的准确度。
ES 可以使用 Completion Suggester 实现搜索建议功能。如果要一个字段支持搜索建议,可以把字段定义为 类型,搜索时使用 搜索。
为了方便演示,重新创建一个索引,写入一些文档:
搜索请求格式:
搜索可以和 搜索一起使用,前者搜索结果封装在响应的 节点中,后者搜索结果封装在响应的 节点中。
搜索请求示例:
官网API:Sort search results
对应文本搜索(全文搜索),搜索结果按搜索词的分词匹配程度(相关性)对匹配的文档打分,然后按分数降序排序。对于 Term 级别的精准查询,每一个匹配文档的分数都一样。在搜索时可以增加 字段手动按某个字段值升序或降序排序。
match 文本搜索(全文搜索)也可以使用 字段排序。如果使用了 字段排序,排序逻辑将忽略匹配度得分,并且不能使用 二次查询评分。
查询请求提供了 子句用于根据指定的一个或多个字段排序。
搜索 排序 请求格式:
对于指定了 子句的查询,返回结果中的文档也包含了 字段,用于表示每一个排序字段的排序值:
按字段值排序请求示例:
按地理距离排序请求示例: