说明:Elasticsearch提供了多种多样的搜索方式来满足不同使用场景的需求,我们可以使用Elasticsearch来进行各种复制的查询,进行数据的检索。
1.1 精准查询
用来查询索引中某个类型为keyword的文本字段,类似于SQL的“=”查询。
创建一个test-3-2-1的索引
PUT test-3-2-1
{
"mappings": {
"properties": {
"id": {
"type": "integer"
},
"sex": {
"type": "boolean"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"born": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"location": {
"type": "geo_point"
}
}
}
}
搜索name为张三的
POST test-3-2-1/_search
{
"query": {
"term": {
"name.keyword": {
"value": "张三"
}
}
}
}
返回的结果中,took表示搜索耗费的毫秒数,_shards中的total代表本次搜索一共使用了多少个分片,该值一般等于索引主分片数。hits里面的total代表一共搜索到多少结果;max_score代表搜索结果中相关度得分的最大值,默认搜索结果会按照相关度得分降序排列;_score代表单个文档的相关度得分;_source是数据的原始JSON内容。
如果想查询用户名为张三和王五的可以这样写。
POST test-3-2-1/_search
{
"query": {
"terms": {
"name.keyword": [
"张三",
"王五"
]
}
}
}
1.2 范围查询
范围查询也很简单,可以返回某个数值或日期字段处于某一区间的数据。区间筛选参数gt表示大于,gte表示大于等于,lt表示小于,lte表示小于等于。由于索引中保存的时间是UTC时间,以下查询表示查询born日期处于2020/09/1100:00:00(UTC)至2020/09/13 00:00:00(UTC)范围内的数据,可以使用format参数自定义查询的日期格式。
POST test-3-2-1/_search
{
"query": {
"range": {
"born": {
"gte": "2020/09/11 00:00:00",
"lte": "2020/09/13 00:00:00",
"format": "yyyy/MM/dd HH:mm:ss"
}
}
}
}
1.3 存在查询
存在(exists)查询用于筛选某个字段不为空的文档,其作用类似于SQL的“is not null”语句的作用。先往索引test-3-2-1中添加一条数据,这条数据有一个age年龄字段。
POST test-3-2-1/_doc/5
{
"id": "5",
"sex": true,
"name": "刘大",
"born": "2020-02-18 00:02:20",
"age": 20,
"location": {
"lat": 21.12,
"lon": -71.34
}
}
然后,使用exists查询查找age字段存在的数据。
POST test-3-2-1/_search
{
"query": {
"exists": {
"field": "age"
}
}
}
1.3 正则查询
正则查询允许查询内容是正则表达式,它会查询出某个字段符合正则表达式的所有文档。例如:
.POST test-3-2-1/_search
{
"query": {
"regexp": {
"name.keyword": ".*大.*"
}
}
}
1.4 匹配搜索
匹配搜索(match query)和术语查询(term query)不一样,匹配搜索会比较搜索词和每个文档的相似度,只要搜索词能命中文档的分词就会被搜索到,而term query要么搜不到,要么搜到的内容就和索引内容一模一样。Match query主要用于对指定的text类型的字段做全文检索。
先给索引ik-text和my_analyzer-text添加一些数据。
PUT ik-text/_doc/1
{
"content":"武汉大学",
"abstract":"200210452014"
}
PUT my_analyzer-text/_doc/1
{
"content":"武汉大学",
"abstract":"200210452014"
}
尝试用IK分词器来测试match query的效果。
POST ik-text/_search
{
"query": {
"match": {
"content": {
"query": "武汉大学是一所好学校",
"analyzer": "ik_max_word"
}
}
}
}
IK分词器有两种分词模式:ik_max_word和ik_smart模式。ik_max_word (常用) 会将文本做最细粒度的拆分,而ik_smart模式是做粗粒度的拆分,下面的可以看他们是如何划分的。
POST _analyze
{
"analyzer": "ik_max_word",
"text": "武汉大学是一所好学校"
}
下面这个可以进行多个条件查询
POST ik-text/_search
{
"query": {
"match_bool_prefix" : {
"content" : "武大 一所 武汉"
}
}
}
1.5 经纬度搜索
经纬度搜索在GIS开发中较为常见,比如你想在地图上搜索有哪些坐标点落在某个圆形、矩形或者多边形的区域内,这时经纬度搜索就会特别管用。
1.5.1 圆形搜索
圆形搜索(geo-distance)用于搜索距离某个圆心一定长度的检索半径之内的全部数据,传参时需要传入圆心坐标和检索半径。
先新建一个索引geo-shop,并添加一些测试数据。
PUT geo-shop
{
"mappings": {
"properties": {
"name":{