一、引用Maven类库
<!--Elastic Search -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>4.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.6.6</version>
</dependency>
其实spring-data-elasticsearch可以不用引入,因为spring-boot-starter-data-elasticsearch包中的版本比较低,我是想引入一个高版本的。
二、修改配置文件application.yml
增加以下的配置:
spring:
elasticsearch:
rest:
uris: http://192.168.50.202:9200
connection-timeout: 1s
read-timeout: 1m
配置好这两步,业务类中就可以使用ElasticsearchRestTemplate对象了。
三、创建实体类(用于JSON文档对象的转换)
package com.hkyctech.tu.core.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author Elwin ZHANG
* @description: 测试ES对象<br />
* @date 2022/8/26 17:12
*/
@Document(indexName = "mysql-test")
@Data
public class TestVo {
@Id
Long id;
@Field(type = FieldType.Text, name = "addr")
String addr;
@Field(type = FieldType.Text, name = "name")
String name;
@Field(type = FieldType.Date, name = "birthday", pattern = "yyyy-MM-dd")
LocalDate birthday;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8",locale = "zh_CN")
@Field(type = FieldType.Date, name = "create_time", pattern = "yyyy-MM-dd HH:mm:ss",format =DateFormat.custom )
LocalDateTime createTime;
}
@Document注解:表示对应一个索引名相关的文档
@Data注解:lombok的,为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法
@Id 注解:表示文档的ID字段
@Field注解:文档字段的注解,对于日期含时间的字段,要写patten和format,不然会无法更新文档对象
@JsonFormat注解:将文档转换成JSON返回给前端时用到
注意日期类型字段不要用java.util.Date类型,要用java.time.LocalDate或java.time.LocalDateTime类型。
四、创建业务类
代码如下,已经测试通过:
package com.hkyctech.tu.core.service;
import com.hkyctech.commons.base.entity.JsonResult;
import com.hkyctech.tu.core.vo.TestVo;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author Elwin ZHANG
* @description: ElasticSearch 服务类<br/>
* @date 2022/8/26 16:59
*/
@Slf4j
@Service
public class ElasticSearchServiceImpl {
@Resource
ElasticsearchRestTemplate elasticsearchTemplate; //直接注入就可以用了
/***
* @description 查询全部数据
*/
public Object testSearchAll(){
Query query=elasticsearchTemplate.matchAllQuery();
return elasticsearchTemplate.search(query, TestVo.class);
}
/***
* @description 精确查询地址字段
* @param keyword 搜索关键字
*/
public Object testSearchAddr(String keyword) {
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
//查询条件
.withQuery(QueryBuilders.queryStringQuery(keyword).defaultField("addr"))
//分页
.withPageable(PageRequest.of(0, 10))
//高亮字段显示
.withHighlightFields(new HighlightBuilder.Field(keyword))
.build();
return elasticsearchTemplate.search(nativeSearchQuery, TestVo.class);
}
/***
* @description 组合查询,查询关键词不分词,关系and
*/
public Object testComboSearchAnd(){
BoolQueryBuilder esQuery=QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("addr", "马鞍山"))
.must(QueryBuilders.termQuery("addr", "广东"));
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
//查询条件
.withQuery(esQuery)
//分页
.withPageable(PageRequest.of(0, 10))
.build();
return elasticsearchTemplate.search(nativeSearchQuery, TestVo.class);
}
/***
* @description 组合查询,查询关键词不分词,关系or
*/
public Object testComboSearchOr(){
BoolQueryBuilder esQuery=QueryBuilders.boolQuery()
.should(QueryBuilders.termQuery("addr", "马鞍山"))
.should(QueryBuilders.termQuery("addr", "广东"));
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
//查询条件
.withQuery(esQuery)
//分页
.withPageable(PageRequest.of(0, 10))
.build();
return elasticsearchTemplate.search(nativeSearchQuery, TestVo.class);
}
/***
* @description 索引或更新文档
* @param vo 文档对象
*/
public JsonResult testPutDocument(TestVo vo){
try {
Object data = elasticsearchTemplate.save(vo);
return JsonResult.getSuccessResult(data,"更新成功");
}catch (Exception e){
// 看http请求响应日志其实操作成功了,但是会报解析出错,可能是spring的bug,这里拦截一下
String message=e.getMessage();
if(message.indexOf("response=HTTP/1.1 200 OK")>0 || message.indexOf("response=HTTP/1.1 201 Created")>0){
return JsonResult.getSuccessResult("更新成功");
}
return JsonResult.getFailResult(e.getStackTrace(),e.getMessage());
}
}
/***
* @description 删除文档
* @param id 文档ID
*/
public JsonResult deleteDocument(String id){
try {
elasticsearchTemplate.delete(id, TestVo.class);
return JsonResult.getSuccessResult("删除成功");
}catch (Exception e){
String message=e.getMessage();
// 看http请求响应日志其实操作成功了,但是会报解析出错,可能是spring的bug,这里拦截一下
if(message.indexOf("response=HTTP/1.1 200 OK")>0 ){
return JsonResult.getSuccessResult("删除成功");
}
return JsonResult.getFailResult(e.getStackTrace(),e.getMessage());
}
}
}
关于Elasticsearch学习暂时到这里了,以后如有学到其他知识再来更新。 :)
网友评论