<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ES-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ES-test</name>
<description>ES-test</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 测试ES
*/
@RestController
public class CrudController {
@Autowired
private RestHighLevelClient client;
/**
* 高亮查询+分页+排序
* @param keyword 本次搜索的值
* @param pageNum 分页页码
* @param pageSize 单页展示条数
* @return
*/
@GetMapping("list/{keyword}/{pageNum}/{pageSize}")
public List<Map<String, Object>> list(@PathVariable("keyword") String keyword,
@PathVariable("pageNum") Integer pageNum,
@PathVariable("pageSize") Integer pageSize) {
// 从ES查出来并指定title,content字段高亮
List<Map<String, Object>> list = highLightSearch2("blog", "title", "content", keyword, pageNum, pageSize);
return list;
}
/**
* 高亮搜索+分页+按照指定字段排序
*
* @param indexName 索引名称
* @param field 需要匹配的字段
* @param field2 需要匹配的字段
* @param keyword 匹配的值
* @param pageNum 分页页码
* @param pageSize 单页展示条数
* @return 返回替换原本内容后的数据
*/
public List<Map<String, Object>> highLightSearch2(String indexName, String field, String field2, String keyword, Integer pageNum, Integer pageSize) {
List<Map<String, Object>> resList = new ArrayList<>();
// 1. 创建 SearchRequest并执行索引名称,名称可以指定多个
SearchRequest searchRequest = new SearchRequest(indexName);
// 2. 创建 SearchSourceBuilder
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//避免匹配空字符串
if("".equals(keyword)){
//设置需要匹配的字段及匹配的值
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
}else{
//设置需要匹配的字段及匹配的值
searchSourceBuilder.query(QueryBuilders.multiMatchQuery(keyword, field, field2));
}
// 设置分页参数
searchSourceBuilder.from((pageNum - 1) * pageSize);
searchSourceBuilder.size(pageSize);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//4.按照score正序排列
// searchSourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC));
//5.按照id倒序排列(score会失效返回NaN)
searchSourceBuilder.sort(SortBuilders.fieldSort("createTime").order(SortOrder.ASC));
// 设置高亮规则
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field(field).field(field2);
//设置高亮代码
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
// 4. 将 SearchSourceBuilder 添加到 SearchRequest
searchRequest.source(searchSourceBuilder);
try {
// 5. 搜索
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
TotalHits totalHits = response.getHits().getTotalHits();
System.out.println("总记录条数"+totalHits.value);
// 6. 查询到的文档
org.elasticsearch.search.SearchHit[] hits = response.getHits().getHits();
for (org.elasticsearch.search.SearchHit hit : hits) {
// 获取到全部字段高亮部分
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
// 用高亮后的结果取代原来字段
Map<String, Object> source = hit.getSourceAsMap();
if (highlightFields.get(field) != null) {
// 获取 指定field部分高亮出的片段
Text[] fragments = highlightFields.get(field).fragments();
// 拼装
StringBuilder builder = new StringBuilder();
for (Text text : fragments) {
builder.append(text);
}
source.put(field, builder.toString());
}
if (highlightFields.get(field2) != null) {
// 获取 指定field部分高亮出的片段
Text[] fragments2 = highlightFields.get(field2).fragments();
// 拼装
StringBuilder builder2 = new StringBuilder();
for (Text text2 : fragments2) {
builder2.append(text2);
}
source.put(field2, builder2.toString());
}
// 将这条记录加入结果集
resList.add(source);
}
} catch (IOException e) {
System.out.println("===执行搜索失败===");
e.printStackTrace();
}
return resList;
}
}