简介:使用springboot2.0.2集成ElasticSearch5.5.1,ElasticSearch5.5.1后文统称es。
一、创建项目
完成的pom文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sun.es</groupId>
<artifactId>spring-boot-es</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--spring整合elasticsearch包-->
<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>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置es
spring:
data:
elasticsearch:
cluster-name: my_es #es 集群名字
cluster-nodes: 192.168.1.104:9300,192.168.1.104:9301 #es集群节点
启动类加载 ElasticsearchRepository接口
@SpringBootApplication
@EnableElasticsearchRepositories(basePackages = "org.sun.es.dao") // 将es操作接口注入到spring容器
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class,args);
}
}
创建实体类
@Document(indexName = "poem",type = "poem",shards = 1, replicas = 0)
public class Poem {
@Id
private long id;
private String title;
private String content;
public Poem(long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
public Poem(String title, String content) {
this.title = title;
this.content = content;
}
public Poem() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
创建es操作接口
public interface PoemRepository extends ElasticsearchRepository<Poem,Long>{
}
创建业务逻辑处理接口和实现类
接口
public interface PoemService {
//保存Poem实体
void save(Poem poem);
//基于title和content进行搜索,返回分页
Page<Poem> search(String title, String content, Pageable pageable);
//基于content进行搜索,返回分页
Page<Poem> search(String content, Pageable pageable);
//返回所有数据集合
Page<Poem> findAll(Pageable pageable);
}
实现类
@Service
public class PoemServiceImpl implements PoemService{
// 被检索的列
private static final String INDEX_TITLE = "title";
private static final String INDEX_CONTENT = "content";
@Autowired
private PoemRepository poemRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Override
public void save(Poem poem) {
poemRepository.save(poem);
}
@Override
public Page<Poem> search(String title, String content, Pageable pageable) {
return poemRepository.findByTitleLikeOrContentLike(title,content,pageable);
}
/**
* 查询:标题必须存在,内容可以不存在
* @param query
* @param pageable
* @return 高亮结果集
*/
@Override
public Page<Poem> search(String query, Pageable pageable) {
// 设置检索条件 matchQuery必须存在 multiMatchQuery可能存在 具体查看--->>>https://blog.csdn.net/lom9357bye/article/details/52852533
QueryBuilder queryTitle = QueryBuilders.matchQuery(INDEX_TITLE, query);
QueryBuilder queryContent = QueryBuilders.multiMatchQuery(query,INDEX_CONTENT);
// BoolQueryBuilder用于组合查询 可以设置多条件 具体查看--->>>https://www.cnblogs.com/xiaocandou/p/8127371.html
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(queryTitle).should(queryContent);
// 给指定列设置高亮标签
HighlightBuilder.Field titleHighLight = new HighlightBuilder.Field(INDEX_TITLE);
titleHighLight.preTags("<span style='color:red'>");
titleHighLight.postTags("</span>");
HighlightBuilder.Field contentHighLight = new HighlightBuilder.Field(INDEX_CONTENT);
contentHighLight.preTags("<span style='color:red'>");
contentHighLight.postTags("</span>");
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder) // 需要执行的es语句
.withHighlightFields(
titleHighLight,
contentHighLight) // 设置高亮
.withPageable(pageable) // 设置分页
.build();
// 使用springboot提供的类执行查询
Page<Poem> poems = elasticsearchTemplate.queryForPage(searchQuery, Poem.class, new SearchResultMapper() {
/**
*
* @param response 返回的结果
* @param aClass 反射的javaBean
* @param pageable 分页对象
* @param <T> 返回泛型结果集
* @return
*/
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
List<Poem> poems = new ArrayList<>();
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
if (hits.totalHits <= 0) {
return null;
}
Poem poem = new Poem();
poem.setId(Long.valueOf(hit.getId()));
poem.setTitle(String.valueOf(hit.getSource().get("title")));
poem.setContent(String.valueOf(hit.getSource().get("content")));
setHighLight(hit, "title", poem);
setHighLight(hit, "content", poem);
poems.add(poem);
}
return new AggregatedPageImpl<>((List<T>) poems);
}
});
return poems;
}
@Override
public Page<Poem> findAll(Pageable pageable) {
return poemRepository.findAll(pageable);
}
/**
* 设置高亮
* @param hit 命中记录
* @param filed 字段
* @param object 待赋值对象
*/
private static void setHighLight(SearchHit hit, String filed, Object object){
//获取对应的高亮域
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlightField = highlightFields.get(filed);
if (highlightField != null){
//取得定义的高亮标签
String highLightMessage = highlightField.fragments()[0].toString();
// 反射调用set方法将高亮内容设置进去
try {
String setMethodName = parSetMethodName(filed);
Class<?> Clazz = object.getClass();
Method setMethod = Clazz.getMethod(setMethodName, String.class);
setMethod.invoke(object, highLightMessage);
} catch (Exception e) {
System.out.println("反射报错");
}
}
}
/**
* 根据字段名,获取Set方法名
* @param fieldName 字段名
* @return Set方法名
*/
private static String parSetMethodName(String fieldName){
if (StringUtils.isBlank(fieldName)){
return null;
}
int startIndex = 0;
if (fieldName.charAt(0) == '_'){
startIndex = 1;
}
return "set" + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
+ fieldName.substring(startIndex + 1);
}
}
创建controller
@Controller
public class WebController {
@Autowired
private PoemServiceImpl poemService;
@Autowired
PoemRepository poemRepository;
@GetMapping("/")
public String index(Model model) {
List<Poem> poems = new ArrayList<>();
poems.add(new Poem(4, "湘春夜月·近清明", "近清明,翠禽枝上消魂,可惜一片清歌,都付与黄昏。欲共柳花低诉,怕柳花轻薄,不解伤春。念楚乡旅宿,柔情别绪,谁与温存。"));
poems.add(new Poem(5, "卜算子·不是爱风尘", "不是爱风尘,似被前缘误。花落花开自有时,总赖东君主。\n" +
"去也终须去,住也如何住!若得山花插满头,莫问奴归处"));
poems.add(new Poem(6, "御街行·秋日怀旧", "纷纷坠叶飘香砌。夜寂静,寒声碎。真珠帘卷玉楼空,天淡银河垂地。年年今夜,月华如练,长是人千里。"));
for (int i = 0; i < poems.size(); i++) {
poemService.save(poems.get(i));
}
model.addAttribute("poems", poems);
return "/index";
}
@ApiImplicitParams({
@ApiImplicitParam(name = "content", value = "输入的关键字", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页显示条数", required = true, dataType = "int", paramType = "query")
})
@PostMapping("/search")
public String search(String content, @RequestParam(value="pageIndex",required=false,defaultValue="0") int pageIndex,
@RequestParam(value="pageSize",required=false,defaultValue="10") int pageSize,Model model) {
Pageable pageable = new PageRequest(pageIndex,pageSize);
Page<Poem> poems = poemService.search(content,pageable);
List<Poem> list = poems.getContent();
model.addAttribute("poems",list);
return "/list";
}
}
启动项目
swagger查看api
es插入数据并回显到页面
根据标题搜索 - 近
至此,整合完毕
源码地址