ElasticSearch: 使用Java Api 操作 ES
创建指定名称的索引库。
·
对索引库作: 增、删、改
Insert
创建索引库 (没有建立映射)
创建指定名称的索引库
@Test
public void createIndexTest() throws Exception {
// 若是对索引库的增删改 都需要创建indicesClient对象, 这个就是一个操作数据库的客户端对象
IndicesClient indicesObject = highLevelClient.indices();
// 新建索引库创建请求: 创建一个索引库, 并指定名称
CreateIndexRequest createIndexRequest = new CreateIndexRequest("hotel");
// 发出索引库创建请求, 并接收索引库创建请求的响应
CreateIndexResponse createIndexResponse = indicesObject.create(createIndexRequest, RequestOptions.DEFAULT);
// 是否创建成功
log.info("\n索引库是否创建成功: {}", createIndexResponse.isAcknowledged());
log.info("\n响应结果: {}", createIndexResponse);
}
创建索引库, 并创建映射
在索引库存在时, 创建映射会失败, 原因: 索引库已存在
// 给指定索引库创建映射树
@Test
public void createMappingTest() throws Exception {
// 获取索引库增删改操作对象
IndicesClient indicesObject = highLevelClient.indices();
// 新建索引库创建请求: 创建一个指定名称的索引库, 并创建映射树
CreateIndexRequest createIndexRequest = new CreateIndexRequest("hotel");
// 新建映射树
createIndexRequest.mapping(
"{\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"address\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\"\n" +
" },\n" +
" \"price\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"score\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"brand\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"city\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"starName\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"business\": {\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"location\": {\n" +
" \"type\": \"geo_point\"\n" +
" },\n" +
" \"pic\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" }, \n" +
" \"isAD\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"all\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\"\n" +
" }\n" +
" }\n" +
" }", XContentType.JSON);
/* 上下两种创建索引方式二选一
// 新建映射树
createIndexRequest.source(
"{\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": true\n" +
" },\n" +
" \"name\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"index\": true,\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"address\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": true\n" +
" },\n" +
" \"price\": {\n" +
" \"type\": \"integer\",\n" +
" \"copy_to\": \"all\",\n" +
" \"index\": true\n" +
" },\n" +
" \"score\": {\n" +
" \"type\": \"integer\",\n" +
" \"index\": true\n" +
" },\n" +
" \"brand\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": true,\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"city\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"starName\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": true,\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"business\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"index\": true,\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"pic\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"location\": {\n" +
" \"type\": \"geo_point\",\n" +
" \"index\": false\n" +
" },\n" +
" \"isAD\": {\n" +
" \"type\": \"boolean\",\n" +
" \"index\": true\n" +
" },\n" +
" \"all\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"index\": true\n" +
" }\n" +
" }\n" +
" }\n" +
"}", XContentType.JSON);
*/
// 发送带有映射树的创建索引库请求, 并接收创建索引库请求的响应
CreateIndexResponse createIndexResponse = indicesObject.create(createIndexRequest, RequestOptions.DEFAULT);
// 是否创建成功
log.info("\n索引库是否创建成功: {}", createIndexResponse.isAcknowledged());
log.info("\n响应结果: {}", createIndexResponse);
}
GET
获取索引库映射
@Test
public void getIndex() throws Exception {
// 获取查询索引库对象, 并指定索引库
GetIndexRequest maomaoIndex = new GetIndexRequest("hotel");
// 发送查询索引库请求
GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(maomaoIndex, RequestOptions.DEFAULT);
// 获取索引树, 先获取索引库, 在获取SourceAsMap, 再获取properties中的属性列表
Object mappings = getIndexResponse.getMappings().get("hotel").getSourceAsMap().get("properties");
// 转换为Json
String jsonString = JSON.toJSONString(mappings);
log.info("Json: " + jsonString);
}
Delete
删除指定的索引库
删除指定索引库
@Test
public void deleteIndexTest() throws Exception {
// 获取删除索引库对象
IndicesClient indicesObject = highLevelClient.indices();
// 新建删除索引库请求: 删除一个指定名称的索引库
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("hotel");
// 发出删除索引库请求, 并接受删除索引库请求的响应
AcknowledgedResponse deleteIndexResponse = indicesObject.delete(deleteIndexRequest, RequestOptions.DEFAULT);
// 判断是否删除成功
log.info("\n Hotel索引库是否删除成功: {}", deleteIndexResponse.isAcknowledged());
log.info("\n响应结果: {}", deleteIndexResponse);
}
对文档作: 增、删、改、查
Insert / Update (ES处理修改时, 是作覆盖式修改)
批量添加 (方案一)
导入数据库中的数据到ES中 (批量导入)
public void createIndexWithMappingWithImportData() throws Exception {
// 获取索引库操作对象
IndicesClient indicesObject = highLevelClient.indices();
// 创建索引库
CreateIndexRequest createIndexRequest = new CreateIndexRequest("hotel");
// 创建映射
createIndexRequest.mapping(
"{\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\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" },\n" +
" \"price\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"score\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"brand\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"city\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"starName\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"business\": {\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"location\": {\n" +
" \"type\": \"geo_point\"\n" +
" },\n" +
" \"pic\": {\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" }, \n" +
" \"isAD\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"all\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" }",
XContentType.JSON
);
// 发送索引库创建请求
CreateIndexResponse createIndexResponse = indicesObject.create(createIndexRequest, RequestOptions.DEFAULT);
log.info("\n索引库创建结果: {}", createIndexResponse.isAcknowledged());
log.info("\n响应结果: {}", createIndexResponse);
// 查询数据库
List<Hotel> hotels = hotelMapper.selectList(null);
// Copy 到 HotelDoc
hotels.forEach(hotel -> {
try {
// 将Hotel Copy To HotelDoc 中
HotelDoc hotelDoc = new HotelDoc(hotel);
// 创建文档
IndexRequest hotelIndex = new IndexRequest("hotel").id(hotel.getId().toString());
// 将HotelDoc转换为Json
String hotelDocToJson = objectMapper.writeValueAsString(hotelDoc);
// 填充内容
hotelIndex.source(hotelDocToJson, XContentType.JSON);
// 发送文档创建请求
IndexResponse indexResponse = highLevelClient.index(hotelIndex, RequestOptions.DEFAULT);
// 获取创建后的文档id
log.info("ES文档, id: {}",indexResponse.getId());
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
批量添加 (方案二)
批量添加 (方案二)
@Test
public void BulkSearchDocument() throws Exception {
// 查询数据库中的所有数据
List<Hotel> hotels = hotelMapper.selectList(null);
// 获取批量添加对象
BulkRequest bulkRequest = new BulkRequest();
// 遍历所有数据
hotels.forEach(hotel -> {
try {
// 查询所有数据
HotelDoc hotelDoc = new HotelDoc(hotel);
// 将查询的结果转换为Json
String hotelDocToJson = objectMapper.writeValueAsString(hotelDoc);
// 设定指定索引库 及 文档id
IndexRequest indexRequest = new IndexRequest("hotel").id(hotel.getId().toString());
// 将Json添加到IndexRequest请求中
indexRequest.source(hotelDocToJson, XContentType.JSON);
// 添加请求
bulkRequest.add(indexRequest);
}catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
});
// 发送批量添加请求
BulkResponse bulkResponse = highLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("批量添加结果: {}", bulkResponse.status());
}
Query
查询指定文档id
指定文档id, 查询文档
public void queryDocument() throws Exception {
// 指定索引库民初, 获取查询文档的请求对象
GetRequest hotel = new GetRequest("hotel").id("36934");
// 发送查询请求
GetResponse getResponse = highLevelClient.get(hotel, RequestOptions.DEFAULT);
// 获取查询结果
String sourceAsString = getResponse.getSourceAsString();
// 将Json转换为HotelDoc实体类
HotelDoc hotelDoc = objectMapper.readValue(sourceAsString, HotelDoc.class);
log.info("hotelDoc: {}", hotelDoc);
}
Delete
删除指定文档id
删除指定文档id
public void deleteDocument() throws Exception {
// 获取指定索引库, 且指定文档id的删除文档对象
var deleteRequest = new DeleteRequest("hotel").id("36934");
// 发送删除文档请求
DeleteResponse deleteResponse = highLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
log.info("deleteResponse: {}", deleteResponse.getId());
}
条件查询
查询所有 (没有特定条件)
public void queryAllDocument() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件: 查询所有
SearchSourceBuilder matchAllQuery = searchRequest.source().query(QueryBuilders.matchAllQuery());
// 设置展示的条目
searchRequest.source().size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 处理查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 获取查询结果集
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取文档内容Json
String searchResult = hit.getSourceAsString();
// 将Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加到集合中
hotelDocs.add(hotelDoc);
}
// 全文查询状态
log.info("\n查询全部状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n查询全部结果: {}", hotelDoc));
}
单字段查询
public void queryOneDocument() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件: 单字段查询
searchRequest.source().query(QueryBuilders.matchQuery("all", "如家"));
// 设置展示条目
searchRequest.source().size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询的结果
String searchResult = hit.getSourceAsString();
// 将结果(Json串) 转换为 JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
hotelDocs.add(hotelDoc);
}
// 单字段查询状态
log.info("\n单字段查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n单字段查询结果: {}", hotelDoc));
}
多字段查询
public void queryManyDocuments() throws Exception {
// 获取查询请求对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件: 多字段查询
searchRequest.source().query(QueryBuilders.multiMatchQuery("如家", "name", "brand"));
// 设置展示条目
searchRequest.source().size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取结果
String searchResult = hit.getSourceAsString();
// 将查询结果转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
hotelDocs.add(hotelDoc);
}
// 多字段查询状态
log.info("\n多字段查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n多字段查询结果: {}", hotelDoc));
}
精准查询 (不会对查询条件分词)
Term (精准值查询)
@Test
public void termSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
TermQueryBuilder queryBuilder = QueryBuilders.termQuery("name", "如家");
searchRequest.source().query(queryBuilder);
// 设置页面大小
searchRequest.source().size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
hotelDocs.add(hotelDoc);
}
// 精确查询状态
log.info("\n精确查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n精确查询结果: {}", hotelDoc));
}
Range (范围查询)
@Test
public void rangeSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件: gte: 大于等于, lte: 小于等于
searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(99).lte(199));
searchRequest.source().size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
hotelDocs.add(hotelDoc);
}
// 范围查询状态
log.info("\n范围查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n范围查询结果: {}", hotelDoc));
}
地理位置查询
圆形
public void geoDistanceSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.geoDistanceQuery("location")
.point(
new GeoPoint(31.21, 121.5)).
distance("15km")
)
.size(1000);
// 发送查询条件
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加到集合
hotelDocs.add(hotelDoc);
}
// 地理坐标查询状态
log.info("\n地理坐标查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n地理坐标查询结果: {}", hotelDoc));
}
矩形
public void geoBoundingBoxSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.geoBoundingBoxQuery("location")
.setCorners(
new GeoPoint(31.1, 121.5),
new GeoPoint(30.9, 121.7)
)
)
.size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 接收结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加到集合
hotelDocs.add(hotelDoc);
}
// 地理坐标查询状态
log.info("\n地理坐标查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n地理坐标查询结果: {}", hotelDoc));
}
组合条件查询
查询全国的酒店名称不为七天的上海的所有酒店, 价格范围大于等于99, 小于等于199, 而且查询的地址位置是31,21, 121.5, 范围半径20km
@Test
public void boolSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.boolQuery()
.must(
QueryBuilders.rangeQuery("price")
.gte(99)
.lte(199))
.mustNot(
QueryBuilders.termQuery("name", "七天"))
.filter(
QueryBuilders.geoDistanceQuery("location")
.point(31.21, 121.5)
.distance("20km")
)
.should(
QueryBuilders.termQuery("city", "上海")
)
)
.size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 接收查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
for (SearchHit hit : searchResponse.getHits()) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json 转换为 JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加查询结果
hotelDocs.add(hotelDoc);
}
// 组合条件查询状态
log.info("\n组合条件查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n组合条件查询结果: {}", hotelDoc));
}
算分查询
查询如家酒店, 对于深圳的如家进行+10分
public void addScoreSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.functionScoreQuery(
QueryBuilders.matchQuery("all", "如家"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("city", "深圳")
,ScoreFunctionBuilders.weightFactorFunction(10f)
)
}
)
.boostMode(CombineFunction.SUM)
)
.size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 接收查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
for (SearchHit hit : searchResponse.getHits()) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json 转换为 JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加查询结果
hotelDocs.add(hotelDoc);
}
// 算分查询状态
log.info("\n算分查询状态: {}", searchResponse.status());
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n算分查询结果: {}", hotelDoc));
}
排序查询
地理位置排序查询
查找离设定经纬度坐标最近的如家酒店
@Test
public void orderSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.matchQuery("all", "如家")
)
.sort(
SortBuilders.geoDistanceSort("location", new GeoPoint(39.76, 116.33)) // SortBuilders.geoDistanceSort("location", 39.76, 116.33) 两者结果一致
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS)
)
.size(1000)
.from(0) // 从第一页开始查询
.size(7) // 每次查询7条, 类似于mysql中的limit, 使用了这个, 就会覆盖query下的size, DSL语句会报错, 但JavaCode不会
;
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 地理位置排序查询状态
log.info("\n地理位置排序查询状态: {}", searchResponse.status());
// 地理位置排序查询总条目
log.error("\n地址位置排序查询总条目: {}", hits.getTotalHits().value);
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// 获取查询出的酒店位置距离设定的位置有多远
Object[] sortValues = hit.getSortValues();
// 若不是经纬度查询, 则距离值则为空, 直接Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 输出查询结果
log.info("\n查询结果: {}", hotelDoc);
log.info("距离设定的位置有: {}km", sortValues[0]);
}
}
指定字段排序查询
倒序查询全国所有如家品牌酒店的价格
@Test
public void sortSearchAll() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders.matchQuery("all", "如家")
)
.sort(
SortBuilders.fieldSort("price")
.order(SortOrder.DESC)
)
.size(1000);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 添加到集合
hotelDocs.add(hotelDoc);
}
// 指定字段排序查询状态
log.info("\n地理位置排序查询状态: {}", searchResponse.status());
// 指定字段排序查询总条目
log.error("\n指定字段排序查询总条目: {}", hits.getTotalHits().value);
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n指定字段排序查询结果: {}", hotelDoc));
}
高亮显示
查询如家酒店, 并高亮显示为粉色
@Test
public void highlightSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.query(
QueryBuilders
.matchQuery("all", "如家")
)
.from(6) // 显示第2页数据
.size(7) // 只显示7条
.highlighter(
SearchSourceBuilder
.highlight()
.field("name")
.requireFieldMatch(false)
.preTags("<font color = 'pink'>")
.postTags("</font>")
);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 收集查询结果
ArrayList<HotelDoc> hotelDocs = new ArrayList<>();
// 处理查询结果
SearchHits hits = searchResponse.getHits();
// 遍历结果集
for (SearchHit hit : hits) {
// 获取查询结果
String searchResult = hit.getSourceAsString();
// Json转换为JavaBean
HotelDoc hotelDoc = objectMapper.readValue(searchResult, HotelDoc.class);
// 处理高亮结果: 获取需要高亮的字段
HighlightField nameHighlightField = hit.getHighlightFields().get("name");
// 判断HighlightField对象不为空, ObjectUtil是MyBatisPlus的工具类
if (ObjectUtils.isEmpty(nameHighlightField)) {
// 获取第一个元素内容
Text newValue = nameHighlightField.getFragments()[0];
// 将Json转换后的JavaBean中指定的属性替换为新的值
hotelDoc.setName(newValue.toString());
}
// 添加到集合
hotelDocs.add(hotelDoc);
}
// 指定字段高亮显示查询状态
log.info("\n指定字段高亮显示查询状态: {}", searchResponse.status());
// 指定字段高亮显示查询总条目
log.error("\n指定字段高亮显示查询总条目: {}", hits.getTotalHits().value);
// 输出所有查询结果
hotelDocs.forEach(hotelDoc -> log.info("\n指定字段高亮显示查询结果: {}", hotelDoc));
}
聚合查询
Bucket (桶查询)
聚合查询: 桶聚合, 查询全国每个城市的酒店数量
@Test
public void bucketSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
// 构建查询条件
searchRequest.source()
.size(0)
.aggregation(
AggregationBuilders
.terms("cityCountAgg") // 桶名称
.field("city") // 统计字段
.order(
BucketOrder
.count(true) // true = asc, false = desc
)
.size(7) // 只展示7条数据
);
// 发送查询请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 处理查询结果: 接收结果必须使用Terms, 并且是ElasticSearch包中的
Terms cityCountAgg = searchResponse.getAggregations().get("cityCountAgg");
// 获取桶
List<? extends Terms.Bucket> cityBuckets = cityCountAgg.getBuckets();
// 遍历结果集
for (Terms.Bucket cityBucket : cityBuckets) {
// 获取统计到的城市名称
String cityName = cityBucket.getKeyAsString();
// 获取统计到的城市的所有酒店数量
long cityCount = cityBucket.getDocCount();
log.info("统计到的城市名称: {}", cityName);
log.info("获取统计到的城市的所有酒店数量: {}", cityCount);
}
}
自动补全
@Test
public void autoCompletionSearch() throws Exception {
// 获取查询对象
SearchRequest searchRequest = new SearchRequest("hotel");
//添加自动补全的查询条件
searchRequest.source()
.suggest(
new SuggestBuilder()
.addSuggestion(
"searchSuggetion"
,SuggestBuilders
.completionSuggestion("suggestion")
.prefix("如")
.skipDuplicates(true)
.size(33)
)
);
//发出请求
SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 处理结果集
CompletionSuggestion searchSuggetion = searchResponse.getSuggest().getSuggestion("searchSuggetion");
List<CompletionSuggestion.Entry.Option> options = searchSuggetion.getOptions();
List<String> result = new ArrayList<>();
//遍历options取出所有的提示内容存储到集合中,返回
for (CompletionSuggestion.Entry.Option option : options) {
result.add(option.getText().toString());
}
log.info("\n自动补全查询结果: {}", result);
}
更多推荐
已为社区贡献1条内容
所有评论(0)