前言
之前分别介绍了ES的一下常用API:索引类、映射类、别名类API和文档类API, 这些API对应关系型数据也就是创建库、表、添加数据等操作,可以让我们开始基本操作, 但数据库本身的意义无非就是存储和搜索,并且搜索的比例会远远大于存储的比例(大约8:2),所以很有必要了解学习搜索类的API
搜索是ElasticSearch的核心功能,ElasticSearch为用户提供了多种搜索方式,大致分为两类:URL Search
和 Request Body Search
。
- URL Search
在URL中使用查询参数 - Request Body Search
使用 Elasticsearch 提供的,基于 JSON 格式的格式更加完备的 Query Dpmain Specific Language (DSL)
本章节主要介绍URL Search
,此搜索方式在生产中或许使用较少,但开发过程中会经常使用,我们在开发过程中会经常遇到校验数据、查看结果等操作,URL Search明显比DSL更加便捷,所以了解学习URL Search还是很有必要的
搜索结构
查询时,通过将参数追加在请求地址url后,类似编程中Get请求方式携带参数。
这种方式简单便捷,适用于临时在命令行使用一些工具,比如curl,快速发出请求,来检索想要的信息;但如果查询请求很复杂,是很难构建的。故主要用于开发中,生产环境几乎很少使用
GET localhost:8888/blog/_search?q=content:keyword&df=title&sort=createtime:desc&from=0&size=10&timeout=1s
{
"profile": "true"
}
参数说明:
-
q
参数指定查询语句,适用Query String Syntax
-
df
默认字段,q参数不指定字段时,df用于设置默认字段 -
sort
排序 -
from
和size
用于分页 - Profile 可以查看查询时如何被执行的
参数 | 说明 |
---|---|
q |
查询字符串(映射到query_string 查询,有关详细信息,请参阅 查询字符串查询)。 |
df |
在查询中未定义字段前缀时使用的默认字段。 |
analyzer |
分析查询字符串时要使用的分析器名称。 |
analyze_wildcard |
是否应分析通配符和前缀查询。默认为false 。 |
batched_reduce_size |
应在协调节点上一次减少的分片结果数。如果请求中潜在的分片数量很大,则应将此值用作保护机制,以减少每个搜索请求的内存开销。 |
default_operator |
要使用的默认运算符可以是AND 或 OR 。默认为OR 。 |
lenient |
如果设置为true将导致忽略基于格式的失败(如向数字字段提供文本)。默认为false。 |
explain |
对于每个命中,包含如何计算命中得分的解释。 |
_source |
设置为false 禁用_source 字段检索。您还可以使用_source_include &检索部分文档_source_exclude ( 有关详细信息,请参阅请求正文文档) |
stored_fields |
每个匹配返回的文档的选择性存储字段,逗号分隔。不指定任何值将导致没有字段返回。 |
sort |
排序执行。可以是fieldName 或 fieldName:asc / 的形式fieldName:desc 。fieldName可以是文档中的实际字段,也可以是特殊_score 名称,表示基于分数的排序。可以有几个sort 参数(顺序很重要)。 |
track_scores |
排序时,设置为true 仍然跟踪分数并将其作为每个匹配的一部分返回。 |
track_total_hits |
设置为false 禁用跟踪与查询匹配的匹配总数。(有关详细信息,请参阅索引排序)。默认为true。 |
timeout |
搜索超时,将搜索请求限制在指定的时间值内执行,并使用在到期时累积的点击数进行保释。默认为无超时。 |
terminate_after |
在达到查询执行将提前终止时,为每个分片收集的最大文档数。如果设置,响应将具有一个布尔字段,terminated_early 以指示查询执行是否实际上已终止。默认为no terminate_after。 |
from |
从命中的索引开始返回。默认为0 。 |
size |
要返回的点击次数。默认为10 。 |
search_type |
要执行的搜索操作的类型。可以是 dfs_query_then_fetch 或query_then_fetch 。默认为query_then_fetch 。有关可以执行的不同搜索类型的更多详细信息,请参阅 搜索类型。 |
allow_partial_search_results |
false 如果请求将产生部分结果,则设置为返回整体故障。默认为true,这将允许在超时或部分失败的情况下获得部分结果。 |
参数详解
输出格式
format
, 该字段用于指定查询结果的返回格式,支持json、text、yaml等,默认为json
GET /${index}/_search?format=${format_type}
例如:
搜索指定索引的文档,以yaml格式输出
-
输入
GET /nav_web_video/_search?format=yaml
-
输出
took: 0 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 5 relation: "eq" max_score: 1.0 hits: - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: 1.0 _source: name: "爱奇艺" url: "https://www.iqiyi.com/" company: "北京爱奇艺科技有限公司" userNum: "120000000" foundName: "龚宇" foundTime: "2010-02-24" ipAddr: "110.242.72.5" desc: "爱奇艺(iQIYI.COM)是拥有海量、优质、高清的网络视频的大型视频网站,专业的网络视频播放平台。爱奇艺影视内容丰富多元,涵盖电影、电视\ 剧、动漫、综艺、生活、音乐、搞笑、财经、军事、体育、片花..." createTime: "2021-03-23" ……
在搜索过程中,我们可以通过指定URL中的参数q
或者df
指定我们需要搜索的字段,如果不指定,将会在所有字段中进行搜索
输出字段
_source
, 该字段用于指定返回数据的指定字段,多个字段以,
分隔,设置为false时,禁用_source
字段检索
_source_include
, 该字段用于指定返回包含的字段
_source_exclude
, 该字段用于指定排除不需要显示的字段
GET /${index}/_search?&format=yaml&_source=${filed1},${filed2},${filed3}
例如:
以指定的字段返回文档数据
-
输入
GET /nav_web_video/_search?&format=yaml&_source=name,company,foundName
-
输出
took: 1 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 5 relation: "eq" max_score: 1.0 hits: - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: 1.0 _source: foundName: "龚宇" name: "爱奇艺" company: "北京爱奇艺科技有限公司" - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.0 _source: foundName: "马化腾" name: "腾讯视频" company: "腾讯科技有限公司" ……
字段排序
sort
,该字段用于对查询的文档进行排序,可接受多个字段排序
GET /${index}/_search?&sort=${field1}:desc,${field2}:asc
例如:
将查询的文档进行排序
-
输入
GET /nav_web_video/_search?&format=yaml&_source=name,foundTime,userNum&sort=userNum:desc,foundTime:desc
-
输出
took: 1 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 5 relation: "eq" max_score: null hits: - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: null _source: userNum: "120000000" foundTime: "2011-04-01" name: "腾讯视频" sort: - 120000000 - 1301616000000 - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: null _source: userNum: "120000000" foundTime: "2010-02-24" name: "爱奇艺" sort: - 120000000 - 1266969600000 - _index: "nav_web_video" _type: "_doc" _id: "s1XLs4gBtZh8w2gvDlGk" _score: null _source: userNum: "102000000" foundTime: "2006-06-21" name: "优酷视频" sort: - 102000000 - 1150848000000 ……
分页处理
from
, 该字段用于指定页码, 从0开始,相当于pageNo
size
, 该字段用于指定每页多少条数据,相当于pageSize如果没有发送这两个参数, Elasticsearch 默认从第一项结果开始(第0 项结果),在回复 中返回 10 项结果
需要注意的是,为了确定第2 页的10 项结果, Elastic search 必须要计算前20 个结果,如果结果集合不断增加,获取某些靠
后的翻页将会成为代价高昂的操作
GET /${index}/_search?&from=${pageNo}&size=${pageSize}
例如:
查询索引下的文档,从第0页开始,每页显示2条文档
-
输入
GET /nav_web_*/_search?&format=yaml&_source=name&from=0&size=2
-
输出
--- took: 1 timed_out: false _shards: total: 3 successful: 3 skipped: 0 failed: 0 hits: total: value: 15 relation: "eq" max_score: 1.0 hits: - _index: "nav_web_game" _type: "_doc" _id: "m1Xpi4gBtZh8w2gvcFFt" _score: 1.0 _source: name: "腾讯游戏" - _index: "nav_web_game" _type: "_doc" _id: "nFXpi4gBtZh8w2gvcFFt" _score: 1.0 _source: name: "百度游戏"
搜索范围
q
, 该参数用于指定搜索的关键词,不使用该参数时代表搜索所有文档,可指定搜索字段,如:q= f i e l d : {field}: field:{keyword}
df
, 如若q
参数未指定搜索字段,将使用此参数携带的字段若
q
和df
参数均为指定搜索字段,将会使用泛搜索
指定字段
# field为指定的具体字段,keyword为搜索的关键字
GET /${index}/_search?q=${field}:${keyword}
例如:
在创建的索引中使用指定字段搜索
-
输入
GET /nav_web_video/_search?format=yaml&q=name:腾讯平台
-
输出
took: 1 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 1 relation: "eq" max_score: 1.1213677 hits: - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.1213677 _source: name: "腾讯视频" url: "https://v.qq.com/" company: "腾讯科技有限公司" userNum: "120000000" foundName: "马化腾" foundTime: "2011-04-01" ipAddr: "113.56.189.242" desc: "腾讯视频致力于打造中国领先的在线视频媒体平台,以丰富的内容、极致的观看体验、便捷的登录方式、24小时多平台无缝应用体验以及快捷分享的产品特\ 性,主要满足用户在线观看视频的需求..." createTime: "2021-06-23"
泛搜索
es中的
_all
元数据,在建立索引的时候,我们插入一条document,它里面包含了多个field,此时,es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field,其中是包含了所有field的值的
# keyword为搜索的关键字
GET /${index}/_search?q=${keyword}
样例:
在创建的索引中,在所有的字段中搜索
-
输入
GET /nav_web_video/_search?format=yaml&_source=name,desc&q=腾讯平台
-
输出
--- took: 3 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 2 relation: "eq" max_score: 1.9663699 hits: - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.9663699 _source: name: "腾讯视频" desc: "腾讯视频致力于打造中国领先的在线视频媒体平台,以丰富的内容、极致的观看体验、便捷的登录方式、24小时多平台无缝应用体验以及快捷分享的产品特\ 性,主要满足用户在线观看视频的需求..." - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: 0.70999944 _source: name: "爱奇艺" desc: "爱奇艺(iQIYI.COM)是拥有海量、优质、高清的网络视频的大型视频网站,专业的网络视频播放平台。爱奇艺影视内容丰富多元,涵盖电影、电视\ 剧、动漫、综艺、生活、音乐、搞笑、财经、军事、体育、片花..."
搜索语法
双引号搜索
双引号搜索, 即Phrase短语搜索,使用双引号括起查询字符串时,它将被视为一个精确短语匹配。只有包含完全相同短语的文档才会被返回
- 双引号内的作为短语精确匹配,不会分词
- 双引号的会进行分词,并且会在所有字段中进行检索匹配
# 括号内的keyword1和keyword2不会进行分词,并且顺序必须一致, 括号外keyword3会进行分词并且泛查询
GET /${index}/_search?q=${field}:"${keyword1} ${keyword2}"${keyword3}
{
"profile": "true"
}
例如
指定索引中搜索"腾讯TV"电影
关键词的文档
-
输入
# 双引号中的"腾讯TV"在所有文档的name字段中无法找到,所以匹配不到;而"都市电影"通过分词后可以在爱奇艺和优酷视频的desc中找到,所以可以匹配 GET /nav_web_video/_search?format=yaml&_source=name&q=name:"腾讯TV"都市电影
-
输出
--- took: 3 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 2 relation: "eq" max_score: 1.5778974 hits: - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: 1.5778974 _source: name: "爱奇艺" - _index: "nav_web_video" _type: "_doc" _id: "s1XLs4gBtZh8w2gvDlGk" _score: 1.453199 _source: name: "优酷视频"
不带双引号搜索
不使用双引号括起查询字符串,则 Elasticsearch 将使用默认分词器对查询字符串进行分析,并根据特定的分析规则处理搜索词汇
q指定字段
q指定字段时,ES会将
距离q最近的关键词
根据设置的分词器进行分词,并在指定的字段中检索相关文档,只要相关字段中包含被分词的内容即可被检索到;空格后面的词依然会被分词器进行分词,但会在所有字段中进行泛搜索q不指定字段时,所有关键词都会进行分词,并在所有字段中进行检索,只要有匹配的即可被检索到
例如:
在指定索引中检索不带双引号的腾讯TV 都市电影
-
输入
# 短语将会被分词分为“腾讯”、“TV”、“都市”、“电影”,"腾讯"和“TV”关键词将会被在name字段中搜索, 其他字段将会在所有字段进行泛搜索 GET /nav_web_video/_search?format=yaml&_source=name&q=name:腾讯TV 都市电影
-
输出
--- took: 2 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 4 relation: "eq" max_score: 1.6777123 hits: - _index: "nav_web_video" _type: "_doc" _id: "slXLs4gBtZh8w2gvDlGk" _score: 1.6777123 _source: name: "芒果TV" - _index: "nav_web_video" _type: "_doc" _id: "sFXLs4gBtZh8w2gvDlGk" _score: 1.5778974 _source: name: "爱奇艺" - _index: "nav_web_video" _type: "_doc" _id: "s1XLs4gBtZh8w2gvDlGk" _score: 1.453199 _source: name: "优酷视频" - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.1213677 _source: name: "腾讯视频"
括号搜索
在ES中,URL查询语法使用的是Lucene查询语法,可以使用括号来分组和控制查询优先级。具体来说,括号可用于将多个条件组合成一个逻辑表达式,并控制它们之间的优先级。
-
布尔操作
-
AND / OR / NOT 或者 && / || / !
-
必须大写
-
title:(matrix NOT reloaded)
# type:BooleanQuery,field中必须包含 keyword1 和 keyword2 GET /${index}/_search?q=${field}:(${keyword1} AND ${keyword2}) #type:BooleanQuery, field中必须包含 keyword1,但不包括 keyword2 GET /${index}/_search?q=${field}:(${keyword1} NOT ${keyword2}) #type:BooleanQuery, field中包含 keyword1,或者包括 keyword2, OR可以省略 GET /${index}/_search?q=${field}:(${keyword1} OR ${keyword2})
样例:
-
输入
# 必须包含咪咕视频和腾讯视频 GET /nav_web_video/_search?format=yaml&_source=name&q=name:(咪咕TV AND 腾讯电影) # 包含咪咕视频或者腾讯视频 GET /nav_web_video/_search?format=yaml&_source=name&q=name:(咪咕TV 腾讯电影) # 必须包含咪咕视频,但不包含腾讯视频 GET /nav_web_video/_search?format=yaml&_source=name&q=name:(咪咕TV NOT 腾讯电影)
-
输出
# 1 必须包含咪咕视频和腾讯视频 --- took: 7 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 0 relation: "eq" max_score: null hits: [] # 2 包含咪咕视频或者腾讯视频 --- took: 23 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 3 relation: "eq" max_score: 2.8478818 hits: - _index: "nav_web_video" _type: "_doc" _id: "tFXLs4gBtZh8w2gvDlGk" _score: 2.8478818 _source: name: "咪咕视频" - _index: "nav_web_video" _type: "_doc" _id: "slXLs4gBtZh8w2gvDlGk" _score: 1.6777123 _source: name: "芒果TV" - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.1213677 _source: name: "腾讯视频" # 3 必须包含咪咕视频,但不包含腾讯视频 --- took: 3 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 2 relation: "eq" max_score: 2.8478818 hits: - _index: "nav_web_video" _type: "_doc" _id: "tFXLs4gBtZh8w2gvDlGk" _score: 2.8478818 _source: name: "咪咕视频" - _index: "nav_web_video" _type: "_doc" _id: "slXLs4gBtZh8w2gvDlGk" _score: 1.6777123 _source: name: "芒果TV"
-
-
加减操作
-
+
表示must -
-
表示nust_not - 样式:title:(+matrix -reloaded)
# BooleanQuery,field 中必须包含 keyword2,不包含 keyword1 GET /${index}/_search?q=${filed}:(-${keyword1} + ${keyword2}) { "profile": "true" }
样例:
-
输入
# BooleanQuery, name中必须包含"腾讯视频", 不包含"咪咕视频" GET /nav_web_video/_search?format=yaml&_source=name&q=name:(-咪咕TV +腾讯电影)
-
输出
--- took: 1 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 1 relation: "eq" max_score: 1.1213677 hits: - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.1213677 _source: name: "腾讯视频"
-
范围查询
year:{2019 TO 2018}
year:[* TO 2018]
-
[]
表示闭区间,指包含端点的区间 -
{}
表示开区间,指不包含端点的区间
样例:
搜索时间范围在2010-02-24(不包含)至2011-04-01(包含)之间的数据
- 输入
#花括号2010-02-24不包含,中括号2011-04-01包含 GET /nav_web_video/_search?format=yaml&_source=name,foundTime&q=foundTime:{2010-02-24 TO 2011-04-01]
- 输出
--- took: 4 timed_out: false _shards: total: 1 successful: 1 skipped: 0 failed: 0 hits: total: value: 1 relation: "eq" max_score: 1.0 hits: - _index: "nav_web_video" _type: "_doc" _id: "sVXLs4gBtZh8w2gvDlGk" _score: 1.0 _source: foundTime: "2011-04-01" name: "腾讯视频"
算术符号
在ES的URL搜索中,可以使用算术符号来进行范围查询或数学运算, 可以使用TO
、<
、>
、=
、AND
等常用符号来进行范围查询, 除此ES还支持基本的算术符号(+、-、*、/)和一些高级数学运算符,例如:^(指数运算)、%(取模运算)、abs、floor、ceil等。
year:>2010
year:(>2010 AND <=2018)
year:(+>2010 AND +<=2018)
- 在计算时间范围时, ES会将时间转换为毫秒时间戳与存储字段进行对比, 即使存储为年月日时分秒, 查询时既可以只使用年或年月进行查询, 因为ES会将传入值转换为时间戳进行对比
- 在查询一段范围时, 可以使用小括号, 中间使用
AND
链接
例如:
#查询foundTime大于2011年的文档
GET /nav_web_video/_search?format=yaml&_source=name,foundTime&q=foundTime:>2011
#查询foundTime大于2011年 小于2015的文档
GET /nav_web_video/_search?format=yaml&_source=name,foundTime&q=foundTime:(>2011 AND <2015)
#查询foundTime大于等于2011年 小于2015的文档
GET /nav_web_video/_search?format=yaml&_source=name,foundTime&q=foundTime:(+>=2011 AND +<2015)
通配符查询
在 Elasticsearch 中,通配符搜索时,URL 字段中多个汉字通配符(* 或 ?)默认是无法匹配的。这是因为中文的分词和字典匹配会影响通配符查询的效果,导致查询结果不准确或者查询失败。此外,通配符查询还会增加查询的时间和复杂度,影响 Elasticsearch 的性能。因此,在 Elasticsearch 中不建议使用多个汉字通配符进行通配符搜索。
通配符查询效率低,占用内容大,不建议使用。特别是放在最前面
-
?代表 1 个字符,* 代表 0 或多个字符
- title:mi?d
- title:be*
#通配符匹配 GET /blog/_search?q=?par* { "profile": "true" }
-
正则表达文章来源:https://www.toymoban.com/news/detail-696860.html
- title:[bt]oy
-
模糊匹配与近似查询文章来源地址https://www.toymoban.com/news/detail-696860.html
- title:befutifl~1
- title:”lord rings” ~2
#模糊匹配 GET /blog/_search?q=elastccssarch~5 { "profile": "true" } #近似查询 GET /blog/_search?q="to docker"~5 { "profile": "true" }
到了这里,关于ES基础篇 常用API之搜索API(URL搜索)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!