ElasticSearch通用工具类

1.pom文件

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.1.1</version>
        </dependency>

2.配置文件和配置类

server.port=8040
#服务名
spring.application.name=provide-search

#=====ElasticSearch   start======
elasticsearch.username=elastic
elasticsearch.password=elastic
elasticsearch.uris=127.0.0.1:9200

 配置文件类

@Getter
@Setter
@PropertySource(value="classpath:application.properties")
@Configuration
public class ESProperties {

    //用户名
    @Value("${elasticsearch.username}")
    private String username;

    //密码
    @Value("${elasticsearch.password}")
    private String password;

    //Elasticsearch http访问路径
    @Value("${elasticsearch.uris}")
    private String httpHost;
}

 初始化es配置

@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Configuration
public class ElasticsearchConfig {

    private final ESProperties esProperties;

    @Bean
    public RestHighLevelClient clientDev() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
                esProperties.getUsername(), esProperties.getPassword()
        ));
        // 初始化ES客户端的构造器
        RestClientBuilder builder = RestClient.builder(httpHostHandlerDev());
        // 异步的请求配置
        builder.setRequestConfigCallback(builder1 -> {
            return builder1;
        });
        // 异步的httpclient连接数配置
        builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
            // 赋予连接凭证
            httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            return httpAsyncClientBuilder;
        });
        return new RestHighLevelClient(builder);
    }

    /**
     * 为了应对集群部署的es,使用以下写法,返回HttpHost数组
     */
    private HttpHost[] httpHostHandlerDev() {
        String[] hosts = esProperties.getHttpHost().split(",");
        HttpHost[] httpHosts = new HttpHost[hosts.length];
        for (int i = 0; i < hosts.length; i++) {
            String ip = hosts[i].split(":")[0];
            int port = Integer.parseInt(hosts[i].split(":")[1]);
            httpHosts[i] = new HttpHost(ip, port, "http");
        }
        return httpHosts;
    }
}

3.查询model模板 ,插入模板

@Data
@ApiModel(value = "es插入")
public class ESInsert implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "索引名称")
    public String indexName;

    @ApiModelProperty(value = "插入对象")
    public List<JSONObject> jsonList;
}

 查询模板

@Data
public class ESParam implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "索引名称")
    public String indexName;

    @ApiModelProperty(value = "开始页码")
    public Integer pageNum;

    @ApiModelProperty(value = "每页数据量")
    public Integer pageSize;

    @ApiModelProperty(value = "查询高亮字段名")
    public String highName;

    @ApiModelProperty(value = "精确查询参数map  参数and连接")
    public Map<String,Object> andMap;

    @ApiModelProperty(value = "精确查询参数map  参数or连接")
    public Map<String,Object> orMap;

    @ApiModelProperty(value = "模糊查询参数map 参数and连接")
    public Map<String,Object> dimmap;

    @ApiModelProperty(value = "模糊查询参数map 参数or连接")
    public Map<String,Object> dimOrMap;
}

修改模板

@Data
@ApiModel(value = "es更新参数")
public class EsUpdate implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "索引")
    public String indexName;

    @ApiModelProperty(value = "文档id")
    public String documentId;

    @ApiModelProperty(value = "jsonObject")
    public JSONObject json;
}

4.查询controller

@RestController
@RequestMapping("/Es")
@Api(tags = "ES测试",description = "ESController")
public class ESController {
    @Autowired
    private EsService esService;

    @GetMapping("/createIndex")
    @ApiOperation("创建索引")
    public ResultVO createIndex(String indexName){
        boolean status = esService.createIndex(indexName);
        return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);
    }


    @GetMapping("/indexExists")
    @ApiOperation("判断索引是否存在")
    public ResultVO indexExists(String indexName){
        boolean status = esService.indexExists(indexName);
        return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);

    }

    @GetMapping("/deleteIndex")
    @ApiOperation("测试删除索引")
    public ResultVO deleteIndex(String indexName){
        Boolean status = esService.deleteIndex(indexName);
        if(status){
            return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);
        }else {
            return new ResultVO<>(999,"删除索引失败",status);
        }
    }

    @GetMapping("/delData")
    @ApiOperation("根据id删除文档")
    public ResultVO delData(String indexName,String id){
        boolean status = esService.delData(indexName, id);
        if(status){
            return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);
        }else {
            return new ResultVO<>(999,"删除文档失败",status);
        }
    }

    /**
     {
        "indexName":"zsq",
        "jsonList":[
            {
                "areaId":"2222222",
                "areaName": "2222222",
                "date": 22222222,
                "name": "2222222"
            },
            {
                "areaId":"333333333",
                "areaName": "3333333333",
                "date": 3333333333,
                "name": "3333333333"
            },
            {
                "areaId":"444444444",
                "areaName": "4444444444",
                "date": 4444444444,
                "name": "444444444"
            }
        ]
     }
     */
    @PostMapping("/addList")
    @ApiOperation("添加文档")
    public ResultVO addList(@RequestBody ESInsert list){
        String indexName = list.getIndexName();
        List<JSONObject> jsonList = list.getJsonList();
        boolean status = esService.addData(indexName, jsonList);
        if(status){
            return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);
        }else {
            return new ResultVO<>(999,"操作失败!",status);
        }
    }

    /**
     {
        "indexName":"zsq",
        "documentId":"zVk8SXgB4FnvgKoT6mQq",
        "json":{
            "areaId":"111",
            "areaName": "强无敌",
            "date": 6666666666,
            "name": "无敌"
        }
     }
     */
    @PostMapping("/updateData")
    @ApiOperation("更新文档") //更新要所有原始数据 ,先查再更新
    public  ResultVO updateData(@RequestBody EsUpdate esUpdate){
        String indexName = esUpdate.getIndexName();
        String documentId = esUpdate.getDocumentId();
        JSONObject jsonObject = esUpdate.getJson();
        boolean status = esService.updateData(indexName, documentId,jsonObject );
        if(status){
            return new ResultVO<>(StatusCode.RESULT_SUCCESS,status);
        }else {
            return new ResultVO<>(999,"操作失败!");
        }
    }

    /**
     * 请求格式
     * {
     *     "highName":"name",
     *     "indexName":"zsq",
     *
     *     "dimmap":{
     *         "areaName":"ang2",
     *         "name":"eng2"
     *     },
     *     "pageNum":1,
     *     "pageSize":20
     * }
     */
    @GetMapping("/queryData")
    @ApiOperation("查询文档---按照id进行查询")
    public ResultVO queryData(String indexName, String documentId) {
        JSONObject jsonObject = esService.queryData(indexName, documentId);
        return new ResultVO<>(StatusCode.RESULT_SUCCESS,jsonObject);
    }

    @PostMapping("/search")
    @ApiOperation("查询")
    public ResultVO search(@RequestBody ESParam esParam){
        try {
            String indexName = esParam.getIndexName();
            Integer pageNum = esParam.getPageNum();
            Integer pageSize = esParam.getPageSize();
            String highName = esParam.getHighName();
            Map<String, Object> map = esParam.getAndMap();
            Map<String, Object> orMap = esParam.getOrMap();
            Map<String, Object> dimmap = esParam.getDimmap();
            Map<String, Object> dimOrMap = esParam.getDimOrMap();
            Map<String, Object> search = esService.search(indexName, pageNum, pageSize, highName,map,dimmap,orMap,dimOrMap);
            return new ResultVO<>(StatusCode.RESULT_SUCCESS,search);
        }catch (Exception e){
            e.printStackTrace();
            throw new GlobalException(999,"查询错误");
        }
    }

}

5.service 实现类

@Service
@Slf4j
public class EsService {

    @Autowired
    RestHighLevelClient esClient;

    //创建索引
    public Boolean createIndex(String indexName) {
        try {
            //1.创建索引请求
            CreateIndexRequest request = new CreateIndexRequest(indexName);
            //2.客户端执行请求 indicessClient , 请求后获取响应
            CreateIndexResponse createIndexResponse =
                    esClient.indices().create(request, RequestOptions.DEFAULT);
            log.info("创建索引 createIndexResponse 的值为 : {}", createIndexResponse.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException(999,"系统错误,创建索引失败");
        }
    }

    /**
     * 判断索引是否存在
     *
     * @param indexName
     * @return
     * @throws IOException
     */
    public boolean indexExists(String indexName) {
        try {
            GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
            boolean exists = esClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
            return exists;
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException(999,"系统错误,判断索引是否存在 失败");
        }
    }


    public Boolean deleteIndex(String indexName) {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(indexName);
            AcknowledgedResponse delete = esClient.indices().delete(request, RequestOptions.DEFAULT);
            log.info("删除索引{}, 返回结果为{}", indexName, delete.isAcknowledged());
            return delete.isAcknowledged();
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException(999,"系统错误,删除索引失败");
        }
    }

    /**
     * 删除文档
     * @param indexName 索引(类似key)
     */
    public boolean delData(String indexName) {
        return delData(indexName, null);
    }

    /**
     * 根据id删除文档
     * @param indexName 索引(类似key)
     * @param id        id
     */
    public boolean delData(String indexName, String id) {
        try {
            DeleteRequest request;
            if (StringUtils.isEmpty(id)) {
                request = new DeleteRequest(indexName);
            } else {
                request = new DeleteRequest(indexName, id);
            }
            DeleteResponse deleteResponse = esClient.delete(request, RequestOptions.DEFAULT);
            RestStatus status = deleteResponse.status();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 批量新增文档
     *
     * @param indexName 索引(类似key)
     * @param list      存储的数据实体类对象
     */
    public boolean addData(String indexName, List<JSONObject> list) {
        try {
            BulkRequest request = new BulkRequest();
            list.forEach(crowdMessageDTO -> {
                String source = JSON.toJSONString(crowdMessageDTO);
                request.add(new IndexRequest(indexName).source(source, XContentType.JSON));
            });
            BulkResponse bulk = esClient.bulk(request, RequestOptions.DEFAULT);
            if (!bulk.hasFailures()) { //是否失败 ,返回false 代表成功
                return true;
            }else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException(999,"系统错误,批量新增文档 失败");
        }
    }

    /**
     * 更新文档
     *
     * @param indexName  索引(类似key)
     * @param documentId 文档id
     * @param jsonObject 实体对象
     */
    public boolean updateData(String indexName, String documentId, JSONObject jsonObject) {
        try {
            UpdateRequest updateRequest = new UpdateRequest(indexName, documentId).doc(JSON.toJSONString(jsonObject), XContentType.JSON);
            // 执行更新
            UpdateResponse update = esClient.update(updateRequest, RequestOptions.DEFAULT);
            GetResult getResult = update.getGetResult();
            int total = update.getShardInfo().getTotal();
            if (total > 0) {
                return true;
            }else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalException(999,"系统错误,更新文档 失败");
        }
    }

    /**
     * 查询文档---按照id进行查询
     *
     * @param indexName  索引(类似key)
     * @param documentId 文档id
     */
    public JSONObject queryData(String indexName, String documentId) {
        try {
            GetRequest getRequest = new GetRequest(indexName, documentId);
            // 查询结果
            GetResponse documentFields = esClient.get(getRequest, RequestOptions.DEFAULT);
            Map<String, DocumentField> fields = documentFields.getFields();
            Map<String, Object> source = documentFields.getSource();// 索引的字段信息
            return (JSONObject) JSONObject.toJSON(source);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通用查询方法
     * @param indexName 索引名称
     * @param pageNum   开始页码
     * @param pageSize  每页数据量
     * @param highName  查询高亮字段名
     * @param queryMap  精确查询参数map  参数and连接
     * @param orMap     精确查询参数map  参数or连接
     * @param dimap     模糊查询参数map 参数and连接
     * @param dimOrMap  模糊查询参数map 参数or连接
     * @return 查询结果
     * @throws Exception 操作错误
     */
    public Map<String, Object> search(String indexName, Integer pageNum, Integer pageSize,
                                      String highName, Map<String, Object> queryMap, Map<String, Object> dimap
            , Map<String, Object> orMap, Map<String, Object> dimOrMap) throws Exception {
        SearchRequest searchRequest = new SearchRequest(indexName);
        //构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = moreCondition(queryMap, dimap, orMap, dimOrMap);//构建多条件查询
        sourceBuilder.query(boolQuery);
        if (!StringUtils.isEmpty(highName)) {
            highlightBuilder(sourceBuilder, highName);
        }
        limit(sourceBuilder, pageNum, pageSize); //构建分页
        sourceBuilder.timeout(TimeValue.timeValueSeconds(60));
        searchRequest.source(sourceBuilder);
        return manageResult(pageNum, pageSize, highName, searchRequest);
    }

    /**
     * 处理结果方法
     * @param pageNum       开始页码
     * @param pageSize      每页数据
     * @param highName      高亮字段
     * @param searchRequest 搜索请求
     * @return map
     * @throws IOException 操作异常
     */
    public Map<String, Object> manageResult(Integer pageNum, Integer pageSize, String highName, SearchRequest searchRequest) throws IOException {
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        JSONArray jsonArray = new JSONArray();
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap(); //原来的结果
            if (!StringUtils.isEmpty(highName)) { //高亮存在,替换高亮
                //解析高亮字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField areaName = highlightFields.get(highName);
                if (areaName != null) {
                    Text[] fragments = areaName.fragments();
                    String new_areaName = "";
                    for (Text text : fragments) {
                        new_areaName += text;
                    }
                    sourceAsMap.put(highName, new_areaName); //高亮字段替换之前字段
                }
            }
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(sourceAsMap));
            jsonArray.add(jsonObject);
        }
        int total = (int) hits.getTotalHits().value; //总数
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("data", jsonArray);
        map.put("pageNum", pageNum);
        map.put("pageSize", pageSize);
        map.put("total", total);
        map.put("pages", total == 0 ? 0 : (total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1));
        return map;
    }


    /**
     * 构建高亮字段
     * @param sourceBuilder 条件构造器
     * @param name          高亮字段
     */
    public void highlightBuilder(SearchSourceBuilder sourceBuilder, String name) {
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field(name); //高亮字段
        highlightBuilder.requireFieldMatch(false); //多个高亮显示
        highlightBuilder.preTags("<span style='color:red'>"); //标签前缀
        highlightBuilder.postTags("</span>");//标签后缀
        sourceBuilder.highlighter(highlightBuilder);
    }

    /**
     * 构建分页
     * @param sourceBuilder 条件构造器
     * @param pageNum       页码
     * @param pageSize      每页数据量
     */
    public void limit(SearchSourceBuilder sourceBuilder, Integer pageNum, Integer pageSize) {
        if (sourceBuilder != null && !StringUtils.isEmpty(pageNum) && !StringUtils.isEmpty(pageSize)) {
            //分页
            sourceBuilder.from((pageNum - 1) * pageSize);  //开始位置
            sourceBuilder.size(pageSize); //结束
        }
    }
    
    /**
     * 多条件查询
     * @param map      精确查询参数map  参数and连接
     * @param orMap    精确查询参数map  参数or连接
     * @param dimap    模糊查询参数map 参数and连接
     * @param dimOrMap 模糊查询参数map 参数or连接
     * @return 多条件构造器
     */
    public BoolQueryBuilder moreCondition(Map<String, Object> map, Map<String, Object> dimap
            , Map<String, Object> orMap, Map<String, Object> dimOrMap) {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //多条件设置  参数and连接
        //matchPhraseQuery是没有用分词起,matchQuery会使用分词器,将我们输入的值进行分割,如:“java动态”会分割成:“java”,“动态”
        if (!CollectionUtils.isEmpty(map)) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), entry.getValue());
                boolQueryBuilder.must(matchQueryBuilder);
            }
        }
        //精确查询参数map  参数or连接
        if (!CollectionUtils.isEmpty(orMap)) {
            for (Map.Entry<String, Object> entry : orMap.entrySet()) {
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), entry.getValue());
                boolQueryBuilder.should(matchQueryBuilder);
            }
        }
        //模糊查询  参数and连接
        if (!CollectionUtils.isEmpty(dimap)) {
            for (Map.Entry<String, Object> entry : dimap.entrySet()) {
                WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(entry.getKey(), "*" + entry.getValue() + "*");
                boolQueryBuilder.must(wildcardQueryBuilder);
            }
        }
        //模糊查询 参数or连接
        if (!CollectionUtils.isEmpty(dimOrMap)) {
            for (Map.Entry<String, Object> entry : dimOrMap.entrySet()) {
                WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(entry.getKey(), "*" + entry.getValue() + "*");
                boolQueryBuilder.should(wildcardQueryBuilder);
            }
        }
        return boolQueryBuilder;
    }


    /***********************************************************************业务类通用方法**********************************************************/
    /**
     * 实体类转Map
     *
     * @param object
     * @return
     */
    public static Map<String, Object> entityToMap(Object object) {
        Map<String, Object> map = new HashMap();
        for (Field field : object.getClass().getDeclaredFields()) {
            try {
                boolean flag = field.isAccessible();
                field.setAccessible(true);
                Object o = field.get(object);
                map.put(field.getName(), o);
                field.setAccessible(flag);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return map;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值