文章目录
- 前言
- 一、环境准备
- 二、RsetAPI操作索引库
- 1.创建索引库
- 2.判断索引库是否存在
- 3.删除索引库
- 二、RsetAPI操作文档
- 1.新增文档
- 2.单条查询
- 3.删除文档
- 4.增量修改
- 5.批量导入
- 6.自定义响应解析方法
- 四、常用的查询方法
- 1.MatchAll():查询所有
- 2.matchQuery():单字段查询
- 3.multiMatchQuery():多字段查询
- 4.termQuery():词条精确值查询
- 5.rangeQuery():范围查询
- 6.bool复合查询
- 7.分页查询
前言
ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES,其中的Java Rest Client又包括两种:
- Java Low Level Rest Client
- Java High Level Rest Client
本文介绍的是Java HighLevel Rest Client客户端API;
一、环境准备
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类
中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
1)引入es的RestHighLevelClient依赖:
dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
2)初始化RestHighLevelClient:
这里为了单元测试方便,我们创建一个测试类HotelIndexTest,然后将初始化的代码编写在
@BeforeEach方法中:
/*** @author 杨树林* @version 1.0* @since 12/8/2023*/@SpringBootTest
class HotelIndexTest{private RestHighLevelClient client;@BeforeEachvoid setUp(){this.client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));}@AfterEachvoid tearDown() throws IOException {this.client.close();}}
3)创建HotelConstants类,定义mapping映射的JSON字符串常量
public class HotelConstants {public static final String MAPPING_TEMPLATE = "{\n" +" \"mappings\": {\n" +" \"properties\": {\n" +" \"id\": {\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"name\":{\n" +" \"type\": \"text\",\n" +" \"analyzer\": \"ik_max_word\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"address\":{\n" +" \"type\": \"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"price\":{\n" +" \"type\": \"integer\"\n" +" },\n" +" \"score\":{\n" +" \"type\": \"integer\"\n" +" },\n" +" \"brand\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"city\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"starName\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"business\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"location\":{\n" +" \"type\": \"geo_point\"\n" +" },\n" +" \"pic\":{\n" +" \"type\": \"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"all\":{\n" +" \"type\": \"text\",\n" +" \"analyzer\": \"ik_max_word\"\n" +" }\n" +" }\n" +" }\n" +"}";
}
二、RsetAPI操作索引库
编写单元测试,实现一下功能:
1.创建索引库
@Testvoid creatHotelIndex() throws IOException {//1、创建Requset对象CreateIndexRequest request = new CreateIndexRequest("hotels");//2、准备请求的参数:DEL语句request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);//3、发起请求client.indices().create(request,RequestOptions.DEFAULT);}
2.判断索引库是否存在
@Testvoid testExistsHotelIndex() throws IOException {//1、创建Requset对象GetIndexRequest request = new GetIndexRequest("hotels");//2、发起请求boolean isExists = client.indices().exists(request,RequestOptions.DEFAULT);System.err.println(isExists ? "索引库已经存在!" : "索引库不存在!");}
3.删除索引库
@Testvoid delHotelIndex() throws IOException {//1、创建Requset对象DeleteIndexRequest request = new DeleteIndexRequest("hotels");//2、发起请求client.indices().delete(request,RequestOptions.DEFAULT);}
二、RsetAPI操作文档
1.新增文档
@AutowiredHotelServiceImpl service;@Testvoid addDocument() throws IOException {// 1.根据id查询酒店数据Hotel hotel = service.getById("36934");// 2.转换为文档类型HotelDoc hotelDoc = new HotelDoc(hotel);// 3.将HotelDoc转jsonString json = JSON.toJSONString(hotelDoc);IndexRequest request = new IndexRequest("hotels").id(hotelDoc.getId().toString());request.source(json, XContentType.JSON);client.index(request, RequestOptions.DEFAULT);}
2.单条查询
@Testvoid getDocument() throws IOException {GetRequest request = new GetRequest("hotels","36934");GetResponse response = client.get(request, RequestOptions.DEFAULT);String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);System.out.println(hotelDoc);}
3.删除文档
@Testvoid delDocument() throws IOException {DeleteRequest request = new DeleteRequest("hotels","36934");client.delete(request,RequestOptions.DEFAULT);}
4.增量修改
api中全局修改与新增一致
@Testvoid UpdateDocument() throws IOException {UpdateRequest request = new UpdateRequest("hotels", "36934");request.doc("name","XX酒店","city","西安","price", "200000","starName", "八星级");client.update(request, RequestOptions.DEFAULT);}
5.批量导入
@Testvoid addBulkRequest() throws IOException {//查询所有酒店信息List<Hotel> hotels = service.list();//1.创建requestBulkRequest request = new BulkRequest();for (Hotel hotel : hotels) {HotelDoc hotelDoc = new HotelDoc(hotel);request.add(new IndexRequest("hotels").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));}client.bulk(request,RequestOptions.DEFAULT);}
6.自定义响应解析方法
void show(SearchResponse response){//解析响应SearchHits searchHits =response.getHits();//获取总条数Long total = searchHits.getTotalHits().value;System.out.println("共搜到"+total+"条数据");//文档数组SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String json = hit.getSourceAsString();System.err.println(json);HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);System.out.println(hotelDoc);}}
四、常用的查询方法
1.MatchAll():查询所有
@Testvoid testMatchAll() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotels");//2、准备DEl,QueryBuilders构造查询条件request.source().query(QueryBuilders.matchAllQuery());//3.执行查询,返回响应结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应show(response);}
2.matchQuery():单字段查询
@Testvoid testMatch() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotels");// 2.准备DSL 参数1:字段 参数2:数据request.source().query(QueryBuilders.matchQuery("all","如家"));//3.执行查询,返回响应结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应show(response);}
3.multiMatchQuery():多字段查询
@Testvoid testMultiMatch() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotels");// 2.准备DSLrequest.source().query(QueryBuilders.multiMatchQuery("如家","name","business"));//3.执行查询,返回响应结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应show(response);}
4.termQuery():词条精确值查询
@Testvoid testTermQuery() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotels");// 2.准备DSLrequest.source().query(QueryBuilders.termQuery("city","上海"));//3.执行查询,返回响应结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应show(response);}
5.rangeQuery():范围查询
@Testvoid testRangeQuery() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotels");// 2.准备DSLrequest.source().query(QueryBuilders.rangeQuery("pirce").gte(100).lte(200));//3.执行查询,返回响应结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应show(response);}
6.bool复合查询
布尔查询是一个或多个查询子句的组合,子查询的组合方式有:
must:必须匹配每个子查询,类似“与”;
should:选择性匹配子查询,类似“或”;
must_not:必须不匹配,不参与算分,类似“非”;
filter:必须匹配,类似“与”,不参与算分一般搜索框用must,选择条件使用filter;
@Testvoid testBool() throws IOException {SearchRequest request = new SearchRequest("hotels");//方式1
// BoolQueryBuilder boolQuery = new BoolQueryBuilder();
// boolQuery.must(QueryBuilders.termQuery("city","上海"));
// boolQuery.filter(QueryBuilders.rangeQuery("price").gte(100).lte(200));
// request.source().query(boolQuery);//方式2request.source().query(new BoolQueryBuilder().must(QueryBuilders.termQuery("city","上海")).filter(QueryBuilders.rangeQuery("price").gte(100).lte(200)));SearchResponse response = client.search(request, RequestOptions.DEFAULT);show(response);}
7.分页查询
@Testvoid testPageAndSort() throws IOException {int page = 1, size = 5;String searchName = "如家";SearchRequest request = new SearchRequest("hotels");// 2.1.queryif(searchName == null){request.source().query(QueryBuilders.matchAllQuery());}else{request.source().query(QueryBuilders.matchQuery("name", searchName));}// 2.2.分页 from、sizerequest.source().from((page - 1) * size).size(size);//2.3.排序request.source().sort("price", SortOrder.DESC);SearchResponse response = client.search(request, RequestOptions.DEFAULT);show(response);}