package cn.itcast.hotel;
import cn.itcast.hotel.constant.EsConstant;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.impl.HotelService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.swing.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* d:文档操作 ,kibana-query查询
* Description: TODO
* ClassName: cn.itcast.hotel.HotelDocTest
* Author: regular
* Version: 1.0
*/
@SpringBootTest
public class HotelDocTest {
@Autowired
private HotelService hotelService;
@Autowired
private RestHighLevelClient client;
/**
* 根据ID查询文档
* @Description: HotelDocTest
*/
@Test
public void getDocTest() throws IOException {
GetRequest getRequest=new GetRequest(EsConstant.HOTEL_INDEX,"36934");
//根据ID查询文档
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
String json = response.getSourceAsString();
HotelDoc hotelDoc= JSONObject.parseObject(json, HotelDoc.class);
System.out.println(hotelDoc);
}
/**
* 添加文档
* @Description: HotelDocTest
*/
@Test
public void addDocTest() throws IOException {
Hotel hotel=hotelService.getById(36934L);//根据ID查询
HotelDoc hotelDoc=new HotelDoc(hotel);
//创建增加文档的请求对象
IndexRequest indexRequest=new IndexRequest(EsConstant.HOTEL_INDEX);
//设置文档ID与数据
indexRequest.id(hotelDoc.getId().toString()).source(JSONObject.toJSONString(hotelDoc), XContentType.JSON);
//执行增加文档的请求
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
String id= response.getId();
System.out.println("id="+id);
}
/**
* 删除文档
* @Description: HotelDocTest
*/
@Test
public void deleteDocTest() throws IOException {
DeleteRequest deleteRequest=new DeleteRequest(EsConstant.HOTEL_INDEX,"36934");
DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
String id=response.getId();
System.out.println("id=" + id);
}
/**
* 修改文档
* @Description: HotelDocTest
*/
@Test
public void updateDocTest(){
Hotel hotel=hotelService.getById(36934L);
HotelDoc hotelDoc=new HotelDoc(hotel);
hotelDoc.setName("北京饭店");
hotelDoc.setPrice(999);
hotelDoc.setAddress("北京市东城区");
UpdateRequest updateRequest=new UpdateRequest(EsConstant.HOTEL_INDEX,"36934");
updateRequest.doc(JSONObject.toJSONString(hotelDoc),XContentType.JSON);
try {
UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
int status = response.status().getStatus();
System.out.println(status);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 批量操作文档
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void bulkRequestTest(){
List<Hotel> hotelList=hotelService.list(null);
List<HotelDoc> hotelDocList=new ArrayList<>(hotelList.size());
for (Hotel hotel : hotelList) {
HotelDoc hotelDoc=new HotelDoc(hotel);
hotelDocList.add(hotelDoc);
}
BulkRequest bulkRequest=new BulkRequest();
for (HotelDoc hotelDoc : hotelDocList) {
//向bulkRequest中添加多个indexRequest请求
IndexRequest indexRequest=new IndexRequest(EsConstant.HOTEL_INDEX);
indexRequest.id(hotelDoc.getId().toString()).source(JSONObject.toJSONString(hotelDoc),XContentType.JSON);
bulkRequest.add(indexRequest);
}
//执行批量操作
try {
client.bulk(bulkRequest,RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据条件查询文档
* @Description: HotelDocTest
*/
@Test
public void matchAllTest() throws IOException {
//1.创建查询请求对象
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
//2.设置封装查询条件
searchRequest.source().query(QueryBuilders.matchAllQuery());
//3.执行查询
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
//4.解析查询结果
printResult(response);
}
/**
* 根据条件查询文档 multi_match
* @Description: HotelDocTest
*/
@Test
public void matchMutiTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source().query(QueryBuilders.multiMatchQuery("北京","name","city","business"));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
//抽取方法返回es数据
private void printResult(SearchResponse response) {
long total = response.getHits().getTotalHits().value;
System.out.println("total=" + total);
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
String json = hit.getSourceAsString();
HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class);
System.out.println(hotelDoc);
}
}
/**
* 根据条件查询文档 term
* @Description: HotelDocTest
*/
@Test
public void termTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source().query(QueryBuilders.termQuery("city","北京"));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 根据条件查询文档 range
* @Description: HotelDocTest
*/
@Test
public void rangeTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(1000).lte(3000));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* geo_distance
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void geoDistanceTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source().query(QueryBuilders
//指定字段
.geoDistanceQuery("location")
//指定距离
.distance("5", DistanceUnit.KILOMETERS)
//指定坐标
.point(31.242201,121.509106));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);//打印结果
}
/**
* 复合查询 -算分查询(根据权重确认显示)
* #给品牌是如家的酒店增加权重积分*10
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void functionScoreTest() throws IOException {
// 创建查询请求
SearchRequest searchRequest = new SearchRequest("hotel");
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(
//QueryBuilders.matchAllQuery(),
QueryBuilders.termQuery("city", "上海"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("brand", "如家"),
ScoreFunctionBuilders.weightFactorFunction(10)
)
}
).boostMode(CombineFunction.MULTIPLY);
// 创建精确查询
searchRequest.source().query(functionScoreQueryBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 复合查询 -布尔查询
*
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void boolTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("all","如家"))
.mustNot(QueryBuilders.rangeQuery("price").gt(400))
.filter(QueryBuilders.geoDistanceQuery("location").point(31.242201,121.509106).distance("5km"));
searchRequest.source().query(boolQueryBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 搜索结果处理 -根据选定普通字段排序
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void sortTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source()
.query(QueryBuilders
//指定字段
.geoDistanceQuery("location")
//指定坐标
.point(31.242201,121.509106)
//指定距离
.distance("5",DistanceUnit.KILOMETERS))
//排序
.sort("score", SortOrder.DESC)
.sort("price", SortOrder.ASC);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 搜索结果处理 -根据地理坐标字段排序
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void geoDistanceSortTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source()
.query(QueryBuilders.matchAllQuery())
//.sort(new GeoDistanceSortBuilder("location",31.242201,121.509106).order(SortOrder.ASC));
.sort(
SortBuilders.geoDistanceSort("location",31.242201,121.509106)
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS)
);
SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 距离升序、分页,有一个深度分页问题
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void geoDistanceSortPageTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source()
.query(QueryBuilders.matchAllQuery())
//排序
.sort(
SortBuilders.geoDistanceSort("location",31.242201,121.509106)
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS)
)
.from(0)
.size(3);
SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
printResult(response);
}
/**
* 高亮显示
* @Description: HotelDocTest
* @Author: regular
* @Version: 1.0
*/
@Test
public void highlightTest() throws IOException {
SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
searchRequest.source()
.query(QueryBuilders.matchQuery("all","如家"))
.highlighter(
new HighlightBuilder()
.field("name")
.requireFieldMatch(false)
.preTags("<font color='red'>")
.postTags("</font>"))
.from(20).size(20);
SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
long total = response.getHits().getTotalHits().value;
System.out.println("总条数=" + total);
for (SearchHit hit : response.getHits().getHits()) {
String json = hit.getSourceAsString();
System.out.println(json);
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//获取高亮片段
HighlightField highlightField = hit.getHighlightFields().get("name");
String text = highlightField.getFragments()[0].toString();
System.out.println(text);
System.out.println(hotelDoc.getName());
}
}
}