导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
添加配置文件
spring:
elasticsearch:
rest:
uris: 192.168.223.223:9200
API使用
-
Rest客户端
RestHighLevelClient
常用方法:
indeces() 方法 返回索引集合
- existst 判断索引是否存在 - delete 删除索引 - create 创建索引
Rest请求
GetIndexRequest 查询索引请求
PostIndexRequest 索引POST请求
PutIndexRequest 索引PUT请求
DeleteIndexRequest 索引DELETE请求
CreateIndexRequest 创建索引请求
BulkRequest 批量操作请求
IndexRequest 索引的操作请求
创建ES实体类(用户封装ES索引的id和数据)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ElasticsearchEntity {
private String id;
private Object data;
}
ES基本操作工具类
@Slf4j
@Repository
public class ElasticsearchDAO {
@Autowired
private RestHighLevelClient client;
/**
* 判断索引存在
* @param indexName
* @return
* @throws IOException
*/
public boolean existIndex(String indexName) throws IOException {
//创建索引查询的请求
GetIndexRequest request = new GetIndexRequest(indexName);
//判断索引是否存在
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
log.info("{}是否存在{}",indexName,exists);
return exists;
}
/**
* 删除索引
* @param indexName
* @throws IOException
*/
public void deleteIndex(String indexName) throws IOException {
//删除索引请求
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
//发送删除请求
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
log.info("{}删除成功",indexName);
}
/**
* 创建索引
* @param indexName
* @throws IOException
*/
public void createIndex(String indexName) throws IOException {
//创建索引请求
CreateIndexRequest request = new CreateIndexRequest(indexName);
//发送创建索引请求
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
log.info("{}创建成功");
}
/**
* 批量插入
* @param indexName
* @param list
* @throws IOException
*/
public void insertBatch(String indexName, List<ElasticsearchEntity> list) throws IOException {
//创建批量操作的请求
BulkRequest request = new BulkRequest(indexName);
//请求加入每个插入数据
list.forEach(entity -> {
//每个索引请求,设置id和数据
request.add(new IndexRequest().id(entity.getId()).source(JSON.toJSONString(entity.getData()),
XContentType.JSON));
});
//执行批量操作
client.bulk(request,RequestOptions.DEFAULT);
log.info("批量插入完成");
}
/**
* 添加或更新数据
*/
public void saveOrUpdate(String indexName,ElasticsearchEntity entity) throws IOException {
IndexRequest request = new IndexRequest(indexName);
request.id(entity.getId());
request.source(JSON.toJSONString(entity.getData()), XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
log.info("{}添加或更新数据成功 {}",indexName, JSON.toJSONString(response));
}
/**
* 通过id批量删除
*/
public <T> void deleteBatch(String indexName, Collection<T> idList) throws IOException {
BulkRequest request = new BulkRequest();
idList.forEach(item -> request.add(new DeleteRequest(indexName, item.toString())));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
log.info("{}批量删除数据成功 {}",indexName, JSON.toJSONString(response));
}
/**
* 通过条件删除对象
*/
public void deleteByQuery(String indexName, QueryBuilder builder) throws IOException {
DeleteByQueryRequest request = new DeleteByQueryRequest(indexName);
request.setQuery(builder);
BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT);
log.info("{}批查询删除数据成功 {}",indexName, JSON.toJSONString(response));
}
/**
* 基本搜索功能
*/
public <T> List<T> search(String indexName, SearchSourceBuilder builder,Class<T> clazz) throws IOException {
// 创建搜索请求
SearchRequest request = new SearchRequest(indexName);
// 指定搜索数据源
request.source(builder);
// 指定搜索获得相应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
List<T> list = new ArrayList<>();
// 获得搜索数据,将数据加到集合
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
// 将json字符串转换成对象
T t = JSON.parseObject(hit.getSourceAsString(), clazz);
list.add(t);
}
return list;
}
/**
* 多条件过滤 排序 分页查询
*/
public <T> PageEntity<T> searchPage(String indexName, Map<String,String> map,
Map<String,String> sort,int from,int size,Class<T> clazz) throws IOException {
SearchRequest request = new SearchRequest(indexName);
SearchSourceBuilder builder = new SearchSourceBuilder();
// 执行布尔查询,通过多个条件进行过滤
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (map != null && map.size() > 0){
for (String key : map.keySet()) {
String value = map.get(key);
if (StringUtils.isNotEmpty(value)){
boolQueryBuilder.filter(QueryBuilders.matchPhraseQuery(key,value));
}
}
}
if (boolQueryBuilder.filter().size() > 0){
builder.query(boolQueryBuilder);
}
//执行排序字段和方式
if(sort != null && sort.size() > 0){
String field = sort.get("field");
String type = sort.get("type");
builder.sort(new FieldSortBuilder(field).order(SortOrder.fromString(type)));
}
//指定分页位置和长度
builder.from(from);
builder.size(size);
request.source(builder);
//处理查询结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
List<T> res = new ArrayList<>();
for (SearchHit hit : hits) {
res.add(JSONUtil.parseObject(hit.getSourceAsString(), clazz));
}
PageEntity<T> entity = new PageEntity<>();
entity.setData(res);
entity.setTotal((int) response.getHits().getTotalHits().value);
entity.setPageSize(size);
return entity;
}
业务层实现(底层调用上面写的工具类)
@Service
public class CourseIndexService implements ICourseService {
// 定义索引名称
public static final String INDEX_NAME = "course";
@Autowired
private RestHighLevelClient client;
@Autowired
private ElasticsearchDAO dao;
// 通过feign调用远程服务的查询所有课程功能
@Autowired
private FeignClient feignClient;
// 初始化es
public void initCourseIndex() throws IOException {
// 如果存在该索引,则删除索引
if (dao.existIndex(INDEX_NAME)){
dao.deleteIndex(INDEX_NAME);
}
// 不存在,则创建该索引
dao.createIndex(INDEX_NAME);
List<ElasticsearchEntity> list = new ArrayList<>();
// 通过feign调用远程服务,查询到所有课程的集合
List<Course> courses = feignClient.selectAll();
System.out.println(courses);
// 将课程集合封装到ES实体类集合
for (int i = 0; i < courses.size(); i++) {
list.add(new ElasticsearchEntity(String.valueOf(i),courses.get(i)));
}
// 批量插入数据
dao.insertBatch("course",list);
}
// 新增或修改索引内的数据
@Override
public void saveOrUpdate(Course course) {
try {
dao.saveOrUpdate(INDEX_NAME,new ElasticsearchEntity(String.valueOf(course.getId()),course));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
// 删除索引内的某条数据
@Override
public void removeById(Long id) {
try {
dao.deleteByQuery(INDEX_NAME, QueryBuilders.termQuery("id", id));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
// 通过课程名字分词查询课程
@Override
public List<Course> searchByCourseName(String courseName) {
try {
// 使用match查询,对课程名称搜索
SearchSourceBuilder builder = new SearchSourceBuilder();
// 执行搜索方式
builder.query(QueryBuilders.matchQuery("courseName",courseName));
List<Course> list = null;
list = dao.search(INDEX_NAME,builder,Course.class);
return list;
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
// 多条件分页查询课程
@Override
public PageEntity<Course> searchCoursePage(Map<String, String> map) {
try {
//获得当前页数和长度
int current = Integer.valueOf(map.get("current"));
int size = Integer.valueOf(map.get("size"));
//获得过滤条件和排序方式
String search = map.get("search");
String sort = map.get("sort");
Map<String, String> searchMap = JSONUtil.parseMap(search);
Map<String, String> sortMap = JSONUtil.parseMap(sort);
//执行分页查询
return dao.searchPage(INDEX_NAME,searchMap,sortMap,(current - 1) * size,size,Course.class);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
控制层
@Slf4j
@RestController
public class CourseSearchController {
@Autowired
private ICourseService courseService;
@PostMapping("/search-courses")
public ResponseEntity<PageEntity<Course>> searchCoursePage(@RequestBody Map<String,String> args){
log.info("搜索参数:{}",args);
PageEntity<Course> page = courseService.searchCoursePage(args);
log.info("搜索结果:{}",page);
return ResponseEntity.ok(page);
}
}
Json工具类
package com.gl.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class JSONUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
public static String toJSON(Object obj){
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
public static <T> T parseObject(String json,Class<T> clazz){
T obj = null;
try {
obj = objectMapper.readValue(json, clazz);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return obj;
}
public static Map<String,String> parseMap(String json){
try {
Map<String,String> map = objectMapper.readValue(json,Map.class);
return map;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}