SpringCloud搭建ElasticSearch多条件查询

导入依赖

     <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;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值