一, Elasticsearch 搜索介绍
1,Elasticsearch 搜索方式主要分为以下两种:
1),URI Search: 此种查询主要是使用 Http 的 Get 方法, 在 URL 中使用查询参数进行查询;
如: http://localhost:9200/kibana_sample_data_ecommerce/_search?q=customer_first_name:Jim
这条 URL 中, q 表示查询的内容, 用来搜索名叫 Jim 的客户. 用 Postman 进行查询, 搜索结果如下图所示:
2),Request Body Search(DSL 查询): 此种查询是使用 Elasticsearch 提供的, 可以采用 Get 或 Post 的方法, 基于 JSON 格式的更加完备的 DSL(Query Domain Specific Language);
如: http://localhost:9200/kibana_sample_data_ecommerce/_search
在请求体中写入:
- {
- "query":{"match_all":{}}
- }
其中 match_all 代表返回所有的文档.
或同样查询 customer_first_name:Jim, 如下:
- {
- "profile": true,
- "query": {
- "match": {"customer_first_name":"Jim"}
- }
- }
用 Postman 进行查询, 结果如下图所示:
took 表示查询用时; hits 表示查到了多少结果, Elasticsearch 默认列出 10 条;_score 表示相关度评分;_source 表示文档原始信息;
所以, 大体上可根据以下语法进行查询:
/_search
查询范围: 集群上所有的索引;
/index-name1/_search
查询范围: 只查询 index-name1 索引;
/index-name1,index-name2/_search
查询范围: 查询 index-name1,index-name2 两个索引;
/index*/_search
查询范围: 查询以 index 开头的索引;
2, 搜索相关性
搜索是用户与搜索引擎的对话, 比较关注的有如下几点:
1) 是否可以找到所有相关的内容;
2) 有多少不相关的内容被返回了;
3) 文档的打分是否合理;
4) 结合业务需求, 平衡结果排名;
3, 搜索结果的衡量
1)Precision - 查准率: 尽可能返回较少的无关文档, 公式为: 返回的相关结果 /(返回的相关结果 + 返回的无关结果)
2)Recall - 查全率: 尽量返回较多的相关文档, 公式为: 返回的相关结果 /(返回的相关结果 + 应该返回但没有返回结果)
3)Ranking - 排名: 是否能够按照相关度进行排序;
二, Elasticsearch URI 搜索操作
通过 URI Query 实现搜索, 语法如下:
- Get /movies/_search?q=2012&df=title_name&sort=year:desc&from=0&size=10&timeout=1s
- {
- "profile":true
- }
q: 指定的查询语句, 使用 Query String 语法;
df: 默认字段, 若不指定, 会对所有字段进行查询;
sort: 用于排序;
from,size: 用于分页;
profile: 用于展示查询是如何被执行的;
1, 指定字段查询, 泛查询
指定字段查询: 就是查询的值是在某个字段范围内进行的查询. 对 movies 索引中的 title 字段做 2012 信息的查询, 查询结果如下图所示:
泛查询: 就是查询的值是对索引中所有字段进行匹配, 如下图所示:
2,Term[词语] 查询与 Phrase[短语] 查询
两者区别在于, 若要查询一条信息, 如 Iron Man
对于 Term 查询, Iron Man 等效于 Iron OR Man;
对于 Phrase 查询,"Iron Man" 等效于 Iron AND Man, 而且要求前后顺序要保持一致;
注意: 对于 Term 查询, 需要加上括号才可以; 对于 Phrase 查询, 需要加上引号才可以;
如下图所示:
3, 布尔查询
布尔表示符: AND/OR/NOT(+,-), 注意: 符号必须大写. 具体操作如下图所示:
在 AND 查询中, 我们会发现查询出 8 条结果, 与 Phrase 查询结果并不相同. 原因在于: Phrase 查询要求查询信息前后顺序必须是一致的, 而 AND 查询并没有这个要求, 因此多出两条查询数据.
在 OR 查询中, 我们会发现与 Term 查询结果是相同的, 包括 profile 中所列出的 description 都是一样的. 不相同的是查询类型, Term 查询是 TermQuery,Or 查询是 BooleanQuery.
4, 范围查询
[]: 表示闭区间;{}: 表示开区间; 如下图所示:
上图中, 开区间查询, 在 profile 中会发现, 查询范围是从 2016 至 2019, 开区间意味着要大于开区间的起始值.
5, 算数符号查询
包括:>,>=,<,<=, 如下图所示:
6, 通配符查询
通配符查询效率低, 占用内存大, 故不建议使用.
?: 代表 1 个字符;*: 代表 0 或多个字符;
7, 模糊 / 近似度匹配查询
从上面两图中可以看出, 近似度查询中的~ 1 表示一个词中允许有一个字母与正确单词不差别;~2 表示对一个短语进行搜索, 可以搜索到缺失 1 个或 2 个词的短语, 2 个以上的不属于此搜索范围.
8, 正则表达式查询
三, Request Body 搜索操作 (DSL 操作)
在 Elasticsearch 中, 一般高阶的搜索操作都是通过 Request Body 来实现.
- // 通过 from size 返回查询结果, 注意: 获取靠后的翻页成本较高.
- post /movies/_search
- {
- "profile": true,
- "from":10,
- "size":20,
- "query": {
- "match": {"title":"iron man"}
- }
- }
- // 通过 sort 对查询结果进行排序, 注意: 排序字段最好是 "数字型" 或 "日期型"
- post /movies/_search
- {
- "profile": true,
- "sort":[{"order_date":"desc"}]
- "from":10,
- "size":20,
- "query": {
- "match": {"title":"iron man"}
- }
- }
- // 通过_source 元数据过滤, 返回相应的字段, 此时, 对 "iron man" 的查询是 iron OR man 的逻辑
- post /movies/_search
- {
- "profile":true,
- "_source":["title","year"],
- "from":10,
- "size":5,
- "sort":[{"year":"desc"}],
- "query":{
- "match": {"title":"iron man"}
- }
- }
- // 若想对 "iron man" 执行 iron AND man 的逻辑, 可按如下操作
- post /movies/_search
- {
- "profile":true,
- "_source":["title","year"],
- "from":10,
- "size":5,
- "sort":[{"year":"desc"}],
- "query":{
- "match"{
- "title":{
- "query":"iron man",
- "operator":"AND"
- }
- }
- }
- }
两者执行结果, 如下图所示:
- // 脚本字段, 通过 script_fields 对返回字段进行加工, 来算出一个新的字段
- post /movies/_search
- {
- "profile":true,
- "script_fields":{
- "new_fields":{
- "script":{
- "lang":"painless",
- "source":"doc['year'].value+'-hello'"
- }
- }
- },
- "_source":["title","year"],
- "from":0,
- "size":10,
- "sort":[{"year":"desc"}],
- "query":{
- "match_all":{}
- }
- }
- // 短语搜索, 注意 slop 的意思是可以在 iron man 之间可以有 1 个其他的字符
- post /movies/_search
- {
- "profile":true,
- "_source":["title","year"],
- "query":{
- "match_phrase":{
- "title":{
- "query":"iron man",
- "slop":"1"
- }
- }
- }
- }
四, Query String 和 Simple Query String 搜索 (也是 DSL 操作)
我们向索引 users 中插入两条文档:
- put /users/_doc/3
- {
- "name":"tang bohu",
- "about":"gongfu,wencai,huahua"
- }
- put /users/_doc/4
- {
- "name":"zhang sanfeng",
- "about":"gongfu,youmo"
- }
- 1,Query String
在 DSL 中也是可以支持类似于 URI Query 的查询.
2,Simple Query String
该种查询的特点:
1) 此种查询类似于 Query String, 但是会忽略错误的语法, 同时只支持部分查询语法;
2) 不支持 AND,OR,NOT, 只会将其作为字符串处理;
3)Term 之间的默认关系是 OR, 通过 Operator 可以指定其他关系;
4) 支持部分逻辑:+,-,|;
注意: Query,Query String,Simple Query String 在使用时, 后两者的灵活性降低了, 但是更容易写; 而第一种灵活性最大, 但是容易出错.
大家可关注我的公众号
来源: https://www.cnblogs.com/supersnowyao/p/11187059.html