【EslaticSearch】ES 搜索引擎详解
ES 搜索引擎
- 查询文档
- 基本语法
- 全文检索
- match
- multi_match
- 精准查询
- term
- range
- 地理查询
- geo_bounding_box 矩形范围
- 获取坐标请点击这里!
- geo_distance 圆形范围
- fuction_score 算分函数
- 算分函数查询
- bool query 复合查询
- 结果处理
- 普通字段排序
- 地理坐标排序
- 分页
- 基本分页
- 高亮
查询文档
基本语法
GET /索引库名/_search
{"query":{"查询类型":{"查询条件":"查询条件值"}}
}
这里的query代表一个查询对象,里面可以有不同的查询属性,ES提供了基于JSON的DSL来定义查询。常见的查询类型包括:
- 查询所有:查询出所有数据,一般测试用。例如:match_all
- 全文检索:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:match_query、multi_match_query
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:term、range
- 地理查询:根据经纬度查询。例如:geo_distance、geo_bounding_box
- 复合查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:bool、function_score
#查询所有
GET /hotel/_search
{"query": {"match_all": {}}
}
效果:
{"took" : 1, //查询花费时间,单位是毫秒"timed_out" : false, //是否超时"_shards" : { //分片信息"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : { //搜索结果"total" : { //搜索到的总条数"value" : 201,"relation" : "eq"},"max_score" : 1.0, //所有结果中文档得分的最高分"hits" : [ //搜索结果的文档对象数组,每个元素是一条搜索到的文档信息{"_index" : "hotel","_type" : "_doc","_id" : "36934","_score" : 1.0,"_source" : {"address" : "静安交通路40号","brand" : "7天酒店","business" : "四川北路商业区","city" : "上海","id" : 36934,"location" : "31.251433, 121.47522","name" : "7天连锁酒店(上海宝山路地铁站店)","pic" : "https://m.tuniucdn.com/fb2/t1/G1/M00/3E/40/Cii9EVkyLrKIXo1vAAHgrxo_pUcAALcKQLD688AAeDH564_w200_h200_c1_t0.jpg","price" : 336,"score" : 37,"starName" : "二钻"}},//省略..........]}
}
全文检索
- 对用户搜索的内容做分词,得到词条
- 根据词条去倒排索引库中匹配,得到文档id
- 根据文档id找到文档,返回给用户
match
match查询:全文检索查询的一种,会对用户输入内容分词,然后去倒排索引库检索,语法:
#match 倒排索引库查询
GET /hotel/_search
{"query": {"match": {"all": "外滩如家"}}
}
效果:
{"took" : 3,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 32,"relation" : "eq"},"max_score" : 5.920452,"hits" : [{"_index" : "hotel","_type" : "_doc","_id" : "434082","_score" : 5.920452,"_source" : {"address" : "复兴东路260号","brand" : "如家","business" : "豫园地区","city" : "上海","id" : 434082,"location" : "31.220706, 121.498769","name" : "如家酒店·neo(上海外滩城隍庙小南门地铁站店)","pic" : "https://m.tuniucdn.com/fb2/t1/G6/M00/52/B6/Cii-U13eXLGIdHFzAAIG-5cEwDEAAGRfQNNIV0AAgcT627_w200_h200_c1_t0.jpg","price" : 392,"score" : 44,"starName" : "二钻"}},
multi_match
multi_match:与match查询类似,只不过允许同时查询多个字段,
语法:
GET /hotel/_search
{"query": {"multi_match": {"query": "","fields": ["field1","field2"]}}
}
示例:
GET /hotel/_search
{"query": {"multi_match": {"query": "外滩如家","fields": ["name","business","brand"]}}
}
效果:
{"took" : 9,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 32,"relation" : "eq"},"max_score" : 4.620212,"hits" : [{"_index" : "hotel","_type" : "_doc","_id" : "434082","_score" : 4.620212,"_source" : {"address" : "复兴东路260号","brand" : "如家","business" : "豫园地区","city" : "上海","id" : 434082,"location" : "31.220706, 121.498769","name" : "如家酒店·neo(上海外滩城隍庙小南门地铁站店)","pic" : "https://m.tuniucdn.com/fb2/t1/G6/M00/52/B6/Cii-U13eXLGIdHFzAAIG-5cEwDEAAGRfQNNIV0AAgcT627_w200_h200_c1_t0.jpg","price" : 392,"score" : 44,"starName" : "二钻"}},
可以看到,match和multi_match两种查询结果是一样的是因为我们将brand、name、business值都利用copy_to复制到了all字段中,虽然效果一样但是 搜索字段越多,对查询性能影响越大,因此建议采用copy_to,然后单字段查询的方式。
精准查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段,它不会对搜索条件分词。常见的有:
- term:根据词条精确匹配,一般搜索keyword类型、数值类型、布尔类型、日期类型字段
- range:根据数值范围查询,可以是数值、日期的范围
term
term: 根据词条进行精确查询,查询过程中不会对词条进行分词处理
语法:
#精确查询
GET /hotel/_search
{"query": {"term": {"FIELD": {"value": "VALUE"}}}
}
示例:
GET /hotel/_search
{"query": {"term": {"city": {"value": "北京"}}}
}
range
范围查找
语法:
GET /indexName/_search
{"query": {"range": {"FIELD": {"gte": 10, // 这里的gte代表大于等于,gt则代表大于"lte": 20 // lte代表小于等于,lt则代表小于}}}
}
示例:
GET /hotel/_search
{"query": {"range": {"price": {"gte": 1000,"lte": 2000}}}
}
地理查询
应用场景:根据经纬度查询常见场景包括:
携程:搜索附近的九点
滴滴:搜索附近的出租车
geo_bounding_box 矩形范围
矩形范围查询,也就是geo_bounding_box查询,查询坐标落在某个矩形范围的所有文档
查询时,需要指定矩形的左上、右下两个点的坐标,然后画出一个矩形,落在该矩形内的都是符合条件的点。
获取坐标请点击这里!
{"query": {"geo_bounding_box": {"location": {"top_left": {//左上坐标"lat": 40.08,"lon": 116.47},"bottom_right": {//右下坐标"lat":39.9,"lon":116.405}}}}
}
geo_distance 圆形范围
附近查询,也叫做距离查询(geo_distance):查询到指定中心点小于某个距离值的所有文档。
也就是说在地图上找一个点作为圆心,以指定距离为半径,画一个圆,落在圆内的坐标都算符合条件
语法:
GET /hotel/_search
{"query": {"geo_distance":{"distance":"15km", // 半径"location":"39.9,116.405" // 圆心 这个坐标是天安门}}
}
fuction_score 算分函数
fuction_score:算分函数查询,可以控制文档相关性算分,控制文档排名
当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列
例如,我们搜索 "虹桥如家"
,结果如下:
elasticsearch会根据词条和文档的相关度做打分,算法由两种:
- TF-IDF算法
- BM25算法,elasticsearch5.1版本后采用的算法
算分函数查询
算分函数关键点是:
- 过滤条件:决定哪些文档的算分被修改
- 算分函数:决定函数算分的算法
- 运算模式:决定最终算分结果
示例:
# 默认查询
GET /hotel/_search
{"query": {"match": {"all": "北京"}}
}# 算法函数查询
GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"all": "北京"}},"functions": [{"filter": {"term": {"brand": "凯悦"}},"weight": 10}],"boost_mode": "multiply"}}
}
bool query 复合查询
bool query:复合查询,也称为布尔查询,它可以利用多种逻辑关系将多个查询条件组装在一起,然后实现复杂搜索
布尔查询是一个或多个查询子句的组合,每一个子句就是一个子查询。子查询的组合方式有:
must:必须匹配每个子查询,类似“与” and
should:选择性匹配子查询,类似“或” or
must_not:必须不匹配,不参与算分,类似“非” not
filter:必须匹配,不参与算分
搜索时,参与打分的字段越多,查询的性能也越差。因此这种多条件查询时,建议这样做:搜索框的关键字搜索,是全文检索查询,使用must查询,参与算分
其它过滤条件,采用filter查询。不参与算分
GET /hotel/_search
{"query": {"bool": {"must": [{"term": {"name": {"value": "如家"}}}],"must_not": [{"range":{"price": {"gte": 400}}}],"filter": [{"geo_distance": {"distance": "10km","location": {"lat": 39.9,"lon": 116.405}}}]}}
}
结果处理
排序
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。
可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
普通字段排序
语法:
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{ //语法一"FIELD": { //排序字段,排序方式 ASC,DESC"order": "desc"}},{ //语法二"field": "desc" //排序字段,排序方式 ASC,DESC}]
}
示例:酒店数据按照用户评价(score)降序排序,评价相同的按照价格(price)升序排序
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": {"order": "desc"},"price": {"order": "asc"}}]
}
地理坐标排序
语法:
GET /indexName/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance" : {"FIELD" : "纬度,经度", // 文档中geo_point类型的字段名、目标坐标点"order" : "asc" // 排序方式}}]
}
获取经纬度点击这里
示例:假设我的位置是:31.034661,121.612282,寻找我周围距离最近的酒店。
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 39.909187,"lon": 116.397455},"order": "asc"}}]
}
分页
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
- from:从第几个文档开始
- size:总共查询几个文档
类似于mysql中的limit ?, ?
基本分页
语法:
GET /hotel/_search
{"query":{"match_all":{}},"from":0, //分页开始的位置,默认为0"size":10, //期望获取的文档总数"sort":[{"price":"asc"}]
}
高亮
** 基本语法:**
GET /hotel/_search
{"query": {"match": {"FIELD": "TEXT"}},"highlight": {"fields": { //指定要高亮的字段"FIELD": {"pre_tags": "<em>", //标记高亮字段的前置标签"post_tags": "</em>" //标记高亮字段的后置标签}}
}
}
示例:
# 查询字段跟高亮字段一致
GET /hotel/_search
{"query": {"match": {"name": "如家"}},"highlight": {"fields": {"name": {"pre_tags": "<em>","post_tags": "</em>"}}}
}# 查询字段跟高亮字段不一致
GET /hotel/_search
{"query": {"match": {"all": "如家"}},"highlight": {"fields": {"name": {"pre_tags": "<em>","post_tags": "</em>","require_field_match": "false"}}}
}
【EslaticSearch】ES 搜索引擎详解相关推荐
- ElasticSearch搜索引擎详解-持续更新中
ElasticSearch搜索引擎详解 1. ElasticSearch概述 1.1 elasticsearch是什么 1.2 全文搜索引擎 1.3 elasticsearch and solr 1. ...
- ElasticSearch——Spring Boot 集成 ES 操作详解
文章目录 ElasticSearch--Spring Boot 集成 ES 操作详解 1.SpringBoot 集成 ES 2.索引的API操作详解 3.文档的API操作详解 ElasticSearc ...
- Elastic stack技术栈学习(十)— springboot集成ES API详解
目录 一.关于索引的API详解 1.1 声明客户端 1.2 创建索引 1.3 获取文档 / 判断文档是否存在 1.4 删除索引 二.关于文档的API详解 2.1 添加文档 2.2 判断文档是否存在 ...
- coreseek mysql_coreseek (sphinx)+ Mysql + Thinkphp搭建中文搜索引擎详解
一, 前言 1,研究coreseek的动机 我有一个自己的笔记博客,经常在上面做一些技术文章分析.在查询一些文章的时候,以前只能将要查询的内容去mysql中用like模糊匹配.在文章多了的情况下,这样 ...
- mysql coreseek_coreseek (sphinx)+ Mysql + Thinkphp搭建中文搜索引擎详解
一, 前言 1,研究coreseek的动机 我有一个自己的笔记博客,经常在上面做一些技术文章分析.在查询一些文章的时候,以前只能将要查询的内容去mysql中用like模糊匹配.在文章多了的情况下,这样 ...
- [网络安全自学篇] 二十六.Shodan搜索引擎详解及Python命令行调用
这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步.前文分享了Web安全学习路线,并实现了最简单的木马和病毒代码.这篇文章将详细讲述S ...
- OpenGL ES入门详解
http://blog.csdn.net/wangyuchun_799/article/details/7736928 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.决定你要支持的Ope ...
- 【Es】es 配置文件详解
1 概述 2.elasticsearch.yml ##################### Elasticsearch Configuration Example ################# ...
- 【ELK】7. elasticsearch linux上操作es命令详解
========== 1.检查ES节点是否正常启动 curl http://192.168.6.16:9200 正常状态: 非正常状态: 1>确保服务是不是正常启动了,端口用的是哪个 2> ...
最新文章
- MyBatis基础-CRUD
- 使用Spring Security 资源服务器来保护Spring Cloud 微服务
- 生成网页没有标题_网页设计公司有哪些?用这个快速建站!
- 前端错误日志收集方案
- 排序算法(4)----快速排序
- python基本函数归整
- Js让光标停在输入框input框最后面
- FlashDevelop 3.0.0 Beta2 released
- 理解Twisted与非阻塞编程
- Python下time模块和datetime模块的使用
- 程序猿为什么逃离北上广?
- 黑苹果 版本 安装 驱动 usb 显卡 声卡 网卡 8169 kext 变色龙
- Dima and Lisa
- 前端网页水印实现方法
- css+js+jq实训笔记
- 【启示录】资源分配体系
- 最全MyBatis核心配置文件总结:java运行环境没有安装或配置错误
- 用大白话解释“什么是ERP?” 看完这篇就全明白了
- 给你双倍工资,你愿意周末加班吗?
- 一、MyBatis-Plus 入门