Kibanan语法:
GET _search
{"query": {"match_all": {}}
}GET /#测试分词器 ik_max_word ik_smart
POST /_analyze
{"text": "黑马程序员学习java太棒了","analyzer": "ik_max_word"
}POST /_analyze
{"text":"传智播客的课程可以白嫖,而且就业率高达95%,奥力给","analyzer": "ik_smart"
}#创建索引库
PUT /heima
{"mappings": {"properties": {"info":{"type": "text","analyzer": "ik_smart"},"email":{"type": "keyword","index": false},"name":{"type": "object","properties": {"firstName":{"type":"keyword"},"lastName":{"type":"keyword"}}}}}
}#查询索引库
GET /heima#删除索引库
DELETE /heima#修改索引库 (只能添加字段)
PUT /heima/_mapping
{"properties":{"age":{"type":"long"}}
}#插入数据
POST /heima/_doc/1
{"info":"黑马程序员java讲师","email":"1142@qq.com","name":{"firstName":"云","lastName":"赵"}
}
#查询文档
GET /heima/_doc/1#删除文档
DELETE /heima/_doc/1#全量修改文档 (id不存在变成新增)
PUT /heima/_doc/1
{"info":"黑马程序员java讲师","email":"dfl@qq.com","name":{"firstName":"云","lastName":"赵"}
}#增量修改
POST /heima/_update/1
{"doc": {"email":"dfl999@qq.com"}
}PUT /hotel
{"mappings": {"properties":{"id":{"type":"keyword"},"name":{"type": "text","analyzer": "ik_max_word","copy_to": "all"},"address":{"type":"keyword","index": false},"price":{"type":"integer"},"score":{"type":"integer"},"brand":{"type":"keyword","copy_to": "all"},"city":{"type": "keyword"},"starName":{"type":"keyword"},"business":{"type":"keyword","copy_to": "all"},"location":{"type": "geo_point"},"pic":{"type": "keyword","index": false},"all":{"type":"text","analyzer": "ik_max_word"}}}
}GET /hotelDELETE /hotel#查询数据
GET /hotel/_doc/61083#批量查询数据
GET /hotel/_searchGET /hotel/_search
{"query":{"match_all": {}}
}#一:全文检索查询 match查询一个字段
GET /hotel/_search
{"query":{"match": {"all": "外滩如家"}}
}#通过使用all和下面的多个字段搜索是一样的,那么使用那个呢?参与搜索的字段越多查询效率越低推荐使用all的方法
#全文检索查询 match查询多个字段
GET /hotel/_search
{"query": {"multi_match": {"query": "外滩如家","fields": ["brand","name","business"]}}
}#二:精确查询 查询的条件它也不需要分词,而且搜索条件要和查找的字段值完全匹配
# 精确查询一般查找keyword、数值、日期、boolean等字段,不会对搜索的字段分词
#分为term:精确值查询 range:范围查询值
GET /hotel/_search
{"query":{"term": {"city": {"value": "上海"}}}
}GET /hotel/_search
{"query":{"range": {"price": {"gte": "100","lte": 300}}}
}#三:地理查询 查询距离中心点15公里的所有值
GET /hotel/_search
{"query":{"geo_distance":{"distance":"15km","location":"31.21,121.5"}}
}#geo_bounding_box 查询值落在矩形范围内的所有文档
GET /hotel/_search
{"query":{"geo_bounding_box":{"location":{"top_left":{"lat":31.1,"lon":121.5},"bottom_right":{"lat":30.9,"lon":121.7}}}}
}#三:复合查询
#相关性算分 function_score:算分函数查询,控制文档的相关性算分,控制文档排名
#算分函数的结果functory_score会与query_score运算得到新的算分 weight:给一个常量值作为函数结果,field_value_factor文档中的某个字段值作为函数结果,random_score:随机生成一个值作为函数结果,script_score:自定义公式,作为函数结果
# filter 过滤条件复合条件的才会重新算分
#boost_mode:算分函数的结果functory_score会与query_score运算方式:加权模式默认multiply 两者相乘,replace:用functory_score替换query_score,其他sum、avg、max、min
GET /hotel/_search
{"query": {"function_score": {"query": {"match":{"all":"外滩"}},"functions": [{"filter": {"term":{"brand":"如家"}},"weight": 10}],"boost_mode": "sum"}}
}#复合查询
#Boolean Query:不是计算相关性算分,而是把多个查询语句组合在一起,形成新的查询,被组合的查询称为子查询
# must_not和filter 不参与算分 果子查询较多,都参与算分,会非常影响性能
# ES会把filer的查询,放到缓存里面,将来在查询的时候,会近一步提高性能
# 除了跟算分相关的,一般是关键字,放到must和should里面
# 其他的都应该放到must_not和filter里面,尽可能的减少算分提高查询的效率# 搜索框的内容关键字的搜索可以放到must里,因为它参与算分 品牌也好价格也好,放到must_not或者filter里面,放到这里面不参与算分
# must:必须匹配每个子查询类似与 should:选择性匹配子查询类似或 must_not:必须不匹配不参与算分类似非 filter:必须匹配,不参与算分#查询名字包含如家,价格不高于400。坐标在31.21,121.5的范围内的
GET /hotel/_search
{"query":{"bool":{"must": [{"match": {"name": "如家"}}],"must_not": [{"range":{"price": {"gt": 400}}}],"filter": [{"geo_distance":{"distance": "10km","location": {"lat": 31.21,"lon": 121.5}}}]}}
}#排序 默认是根据算分的score来排序的,可以排序的字段有keyword 一旦进行了排序_score就没有值了
GET /hotel/_search
{"query":{"match_all": {}},"sort":[{"_geo_distance":{"location":"31.21,121.5","order":"asc","unit":"km"}}]
}#根据用户评价降序排序,评价相同按照价格排序
GET /hotel/_search
{"query":{"match_all": {}},"sort": [{"score": {"order": "desc"},"price":{"order": "asc"}}]
}# 查询按照指定坐标的距离升序排序
GET /hotel/_search
{"query":{"match_all": {}},"sort":[{"_geo_distance":{"location":{"lat": 31.21,"lon": 121.5},"order":"asc","unit":"km"}}]
}#分页 ,ES底层采用倒排索引,它的结构是不利于做分页的,实际上采用的是逻辑上的分页,比如查990到1000的数据,对ES来讲它或查询0到1000的所有数据,然后去截取990-1000的部分
GET /hotel/_search
{"query":{"match_all": {}},"sort":[{"price":"asc"}],"from":20,"size":10
}# 会产生深度分页问题
GET /hotel/_search
{"query":{"match_all": {}},"sort":[{"price":"asc"}],"from":9991,"size":10
}# 高亮
# ES搜索的字段必须与高亮的字段必须一致,如果不一致,需要添加require_field_match 默认是高亮字段和搜索字段匹配
GET /hotel/_search
{"query":{"match":{"all":"如家"}},"highlight": {"fields": {"name": {"require_field_match": "true"}}}
}#如果不一致,需要添加require_field_match:false
GET /hotel/_search
{"query":{"match":{"brand":"如家"}},"highlight": {"fields": {"name": {"require_field_match": "false","pre_tags": "<em>","post_tags": "</em>"}}}
}#搜索处理的整体语句
GET /hotel/_search
{"query":{"match":{"name":"如家"}},"from":0, "size": 20,"sort":[{"price":"asc"},{"_geo_distance": {"location": "31.21,121.5","order": "asc","unit": "km"}}],"highlight": {"fields": {"name": {"pre_tags": "<em>","post_tags": "</em>"}}}
}
Idea操作ES:
package cn.itcast.hotel;import cn.itcast.hotel.constants.HotelIndexConstants;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.CollectionUtils;import java.io.IOException;
import java.util.List;
import java.util.Map;@SpringBootTest
class HotelIndexTestCopy {private RestHighLevelClient client;//单元测试里面的注解,提前完成对象的初始化@BeforeEachvoid setUp(){this.client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.73.129:9200")));}//销毁注解@AfterEachvoid tearDown() throws IOException {this.client.close();}//所有的单元测试,都会先运行BeforeEach 最后运行@AfterEach@Testvoid testInit(){System.out.println(client+"===================");}//创建表@Testvoid createHotelIndex() throws IOException {//1.创建Request对象CreateIndexRequest request=new CreateIndexRequest("hotel");//2.准备请求的参数DSL语句request.source(HotelIndexConstants.MAPPING_TEMPLATE,XContentType.JSON);//3.发送请求 client.indices()返回值是IndicesClient对象里面封装了操作索引库的APIclient.indices().create(request,RequestOptions.DEFAULT);}//删除表@Testvoid testDeleteHotelIndex() throws IOException {//1.创建Request对象DeleteIndexRequest request=new DeleteIndexRequest("hotel");//发起请求client.indices().delete(request,RequestOptions.DEFAULT);}//判断表是否存在@Testvoid testExistHotelIndex() throws IOException {//1.创建Request对象GetIndexRequest request=new GetIndexRequest("hotel");//发起请求boolean exist=client.indices().exists(request,RequestOptions.DEFAULT);System.out.println(exist ? "表存在!":"表不存在!");}@Autowiredprivate IHotelService hotelService;//添加数据@Testvoid addDocumen() throws IOException {//根据id查询酒店数据Hotel hotel=hotelService.getById(61083);System.out.println(hotel);//转换对象类型HotelDoc hotelDoc=new HotelDoc(hotel);System.out.println(hotelDoc);//准备request对象IndexRequest request=new IndexRequest("hotel").id(hotel.getId().toString());//准备json数据request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);//发送请求 client.index() :index表示给文档创建倒排索引client.index(request,RequestOptions.DEFAULT);System.out.println("新增文档成功!");}//查询数据 根据id查询数据@Testvoid selectDocumen() throws IOException {//创建requestGetRequest request=new GetRequest("hotel","61083");//发送请求得到结果GetResponse response=client.get(request,RequestOptions.DEFAULT);//解析结果String json=response.getSourceAsString();System.out.println("解析的json数据:"+json);//利用JSON反序列化为java对象HotelDoc hotelDoc=JSON.parseObject(json,HotelDoc.class);System.out.println("转化的java对象:"+hotelDoc);}//更新数据@Testvoid updateDocument() throws IOException {//创建requestUpdateRequest request=new UpdateRequest("hotel","61083");//准备参数request.doc("price","666","startName","四钻");//发送请求client.update(request,RequestOptions.DEFAULT);System.out.println("更新成功");}//删除数据@Testvoid deleteDocumen() throws IOException {//创建requestDeleteRequest request=new DeleteRequest("hotel","61083");//发送请求client.delete(request,RequestOptions.DEFAULT);System.out.println("删除数据成功");}//批量添加数据@Testvoid insertBulk() throws IOException {//批量查询数据List<Hotel> hotels=hotelService.list();//创建Bulk请求BulkRequest request=new BulkRequest();//准备参数 添加多个新增的Requestfor (Hotel hotel:hotels){//转换java类型HotelDoc hotelDoc=new HotelDoc(hotel);//创建新增文档的Requestrequest.add(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));}//发送请求client.bulk(request,RequestOptions.DEFAULT);System.out.println("批量添加成功!");}/*** @description: DSL查询分类DSL查询分类 es检索数据* @param: null* @return:* @author Administrator* @date: 2025/3/8 14:03*///查询数据 查询所有 DSL是通过HightLevelRestClient 中的source()来实现的,里面包含了查询、排序、分页、高亮//QueryBuilders 里面包含了各种查询方法@Testvoid MallAll() throws IOException {//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数request.source().query(QueryBuilders.matchAllQuery());//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析结果handResponse(response);}//查询数据 全文检索查询 match_query multi_match_query@Testvoid Match() throws IOException {//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数request.source().query(QueryBuilders.matchQuery("all","如家"));//multi_match_query//request.source().query(QueryBuilders.multiMatchQuery("如家","name","business"));//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析响应方法封装handResponse(response);}//查询数据 精确查询 term range@Testvoid termMatch() throws IOException {//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数request.source().query(QueryBuilders.termQuery("city","上海"));//range//request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析响应方法封装handResponse(response);}//查询数据 复合查询 bool@Testvoid Bool() throws IOException {//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数BoolQueryBuilder boolQuery=new BoolQueryBuilder();//添加termboolQuery.must(QueryBuilders.termQuery("city","上海"));//添加rangeboolQuery.filter(QueryBuilders.rangeQuery("price").lte(300));request.source().query(boolQuery);//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析响应方法封装handResponse(response);}//排序、分页@Testvoid testPageAndSort() throws IOException {//页面,每页大小int page=1,size=5;//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数request.source().query(QueryBuilders.matchAllQuery());//排序request.source().sort("price", SortOrder.ASC);//分页request.source().from((page-1)*size).size(5);//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析结果handResponse(response);}//解析方法private static void handResponse(SearchResponse response) {//解析结果SearchHits searchHits= response.getHits();//查询总条数Long total=searchHits.getTotalHits().value;System.out.println("共搜索到"+total+"条数据");//查询结果数组SearchHit[] hits=searchHits.getHits();for(SearchHit hit: hits){//得到jsonString json=hit.getSourceAsString();System.out.println("json数据:"+json);}}//高亮显示@Testvoid Heighlight() throws IOException {//准备requestSearchRequest request=new SearchRequest("hotel");//组织DSL参数request.source().query(QueryBuilders.matchQuery("all","如家"));//高亮request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));//发送请求,得到响应结果SearchResponse response=client.search(request,RequestOptions.DEFAULT);System.out.println("返回的数据"+response);//解析结果handResponseHighLight(response);}//解析方法private static void handResponseHighLight(SearchResponse response) {//解析结果SearchHits searchHits= response.getHits();//查询总条数Long total=searchHits.getTotalHits().value;System.out.println("共搜索到"+total+"条数据");//查询结果数组SearchHit[] hits=searchHits.getHits();for(SearchHit hit: hits){//得到jsonString json=hit.getSourceAsString();System.out.println("json数据:"+json);//反序列化HotelDoc hotelDoc=JSON.parseObject(json,HotelDoc.class);//获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (!CollectionUtils.isEmpty(highlightFields)){//根据字段名获取高亮结果HighlightField highlightField=highlightFields.get("name");if (highlightField!=null){//获取高亮String name=highlightField.getFragments()[0].string();//覆盖不高亮的字段hotelDoc.setName(name);}}System.out.println("hotelDoc:"+hotelDoc);}}}