ElasticSearch 海量数据查询

ElasticSearch 海量数据查询elasticsearc 海量数据查询 使用 RestHighLeve 多条件精确查询 多条件模糊查询 批量查询 全量查询

1、ES数据格式配置

/ * ES数据格式配置 * * @author Lance * @version 1.0 * @data 2022/03/24 23:12 */ public class SearchAllBuilder { 
    / * 索引名称 */ private String indices; / * 类型 */ private String types; / * 查询条件 */ private SearchSourceBuilder searchSourceBuilder; / * 符号 */ private RequestOptions options = RequestOptions.DEFAULT; / * 属性命名策略 */ private Integer propertyNamingStrategy = Constant.ORIGINAL; public SearchAllBuilder() { 
    } public SearchAllBuilder indices(String indices) { 
    this.indices = indices; return this; } public SearchAllBuilder types(String types) { 
    this.types = types; return this; } public SearchAllBuilder searchSourceBuilder(SearchSourceBuilder searchSourceBuilder) { 
    this.searchSourceBuilder = searchSourceBuilder; return this; } public SearchAllBuilder options(RequestOptions options) { 
    this.options = options; return this; } public SearchAllBuilder propertyNamingStrategy(Integer propertyNamingStrategy) { 
    this.propertyNamingStrategy = propertyNamingStrategy; return this; } public String getIndices() { 
    return indices; } public String getTypes() { 
    return types; } public SearchSourceBuilder getSearchSourceBuilder() { 
    return searchSourceBuilder; } public RequestOptions getOptions() { 
    return options; } public Integer getPropertyNamingStrategy() { 
    return propertyNamingStrategy; } } 

2、ES 服务常量

/ * ES 服务常量 * * @author Lance * @version 1.0 * @data 2022/03/24 23:12 */ public interface Constant { 
    / * ES原生转换 */ Integer ORIGINAL = 1; / * ES下划线转驼峰 */ Integer UNDERSCORE_TO_CAMEL = 2; } 

3、Lambda获取字段属性

/ * 获取字段名 * * @author Lance * @version 1.0 * @data 2022/03/24 16:15 */ public class LambdaUtils { 
    public static <T, R> String getfieldName(TypeFunction<T, R> typeFunction) { 
    return TypeFunction.getLambdaColumnName(typeFunction); } } 

4、函数式接口

/ * 函数式接口 - 反射 Lambda获取属性值 * * @param 
   
     * @param 
    
      * @author Lance * @version 1.0 * @data 2022/03/24 15:11 */ 
     
    @FunctionalInterface public interface TypeFunction<T, R> extends Serializable, Function<T, R> { 
    / * 获取列名称 * * @param lambda * @return String */ static String getLambdaColumnName(Serializable lambda) { 
    try { 
    Method method = lambda.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); SerializedLambda serializedLambda = (SerializedLambda) method.invoke(lambda); String getter = serializedLambda.getImplMethodName(); String fieldName = Introspector.decapitalize(getter.replace("get", "")); return fieldName; } catch (ReflectiveOperationException e) { 
    throw new RuntimeException(e); } } } 

5、ES 查询接口

package com.badger.service; import com.badger.config.SearchAllBuilder; import com.badger.config.SearchTermDTO; import org.apache.poi.ss.formula.functions.T; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.springframework.lang.NonNull; import java.io.IOException; import java.util.HashMap; import java.util.List; / * ES 查询接口 * * @author Lance * @version 1.0 * @data 2022/03/24 23:25 */ public interface EsSearchApiService { 
    / * 查询全量(其实也是分页循环查询) * * @param searchAllBuilder 查询所有的builder * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> List<T> searchAll(SearchAllBuilder searchAllBuilder, Class<T> rClass) throws IOException; / * 指定字段查询 * * @param indexName 索引名称 * @param field 字段名称 * @param value 字段值 * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> T searchField(String indexName, String field, Object value, Class<T> rClass) throws IOException; / * 同一个字段条件查询 * 例如:orderSn["2033-SHEN-AA","2033-SHEN-CC","2033-SHEN-BB"] * * @param indexName 索引名称 * @param field 字段名称 * @param value 字段值 * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> List<T> searchField(String indexName, String field, Object[] value, Class<T> rClass) throws IOException; / * 多条件查询 - 【精确匹配】 * * @param indexName 索引名称 * @param queryInfo 查询条件 * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> List<T> searchMultipleEq(String indexName, HashMap<String, Object> queryInfo, Class<T> rClass) throws IOException; / * 自定义查询条件 * * @param indexName 索引名称 * @param builder 查询条件封装 - 用 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> List<T> search(String indexName, SearchSourceBuilder builder, Class<T> rClass) throws IOException; / * 多条件查询 - 【模糊匹配】 * * @param indexName 索引名称 * @param queryInfo 查询条件 * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> List<T> searchMultipleLike(String indexName, HashMap<String, Object> queryInfo, Class<T> rClass) throws IOException; / * 修改 * * @param indexName 索引名称 * @param type 类型 * @param id id * @param updateData 修改的字段和值 * @return 更新成功记录数 * @throws IOException 抛出io异常 */ Boolean update(String indexName, String type, String id, HashMap<String, Object> updateData) throws IOException; / * 修改 * * @param indexName 索引名称 * @param type 类型 * @param id id * @param updateData 修改的对象 * @return 更新成功记录数 * @throws IOException 抛出io异常 */ Boolean update(String indexName, String type, String id, Object updateData) throws IOException; / * 分组查询 * * @param searchAllBuilder 查询所有的builder * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    <T> SearchTermDTO searchTerm(SearchAllBuilder searchAllBuilder, String termName, Class<T> rClass) throws IOException; } 

6、ES 查询查询业务类

package com.badger.service.impl; import com.alibaba.fastjson.JSON; import com.badger.config.SearchTermDTO; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import cn.hutool.core.collection.CollectionUtil; import com.badger.config.SearchAllBuilder; import com.badger.constant.Constant; import com.badger.service.EsSearchApiService; import com.badger.utils.MapObjectUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; / * ES 订单查询 * * @author Lance * @version 1.0 * @data 2022/03/24 23:25 */ @Slf4j @Service @AllArgsConstructor public class EsSearchApiServiceImpl implements EsSearchApiService { 
    private final RestHighLevelClient client; private static final String COMMA_SEPARATE = ","; / * 查询全量(其实也是分页循环查询) * * @param indices 索引名称,多个时逗号分隔 * @param types 索引类型名称,多个时逗号分隔 * @param searchSourceBuilder 查询的builder * @param options 请求类型 * @param tClass 返回对象的类 * @param propertyNamingStrategy 转换策略(PropertyNamingStrategyConstant.class) * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    public <T> List<T> searchAll(@NonNull String indices, @NonNull String types, @NonNull SearchSourceBuilder searchSourceBuilder, @NonNull RequestOptions options, @NonNull Class<T> tClass, Integer propertyNamingStrategy) throws IOException { 
    // 校验索引 String[] indexArray = indices.split(COMMA_SEPARATE); Objects.requireNonNull(indices, "indices must not be null"); for (String index : indexArray) { 
    Objects.requireNonNull(index, "index must not be null"); } // 校验类型 Objects.requireNonNull(types, "types must not be null"); String[] typeArray = types.split(COMMA_SEPARATE); for (String type : typeArray) { 
    Objects.requireNonNull(type, "type must not be null"); } if (Constant.ORIGINAL.equals(propertyNamingStrategy)) { 
    } else if (Constant.UNDERSCORE_TO_CAMEL.equals(propertyNamingStrategy)) { 
    } else { 
    throw new RuntimeException("propertyNamingStrategy is not found"); } return searchAll(indexArray, typeArray, searchSourceBuilder, options, tClass, propertyNamingStrategy); } / * 查询全量(其实也是分页循环查询) * * @param indices 索引名称数组 * @param types 索引类型名称数组 * @param searchSourceBuilder 查询的builder * @param options 请求类型 * @param tClass 返回对象的类 * @param propertyNamingStrategy 转换策略(PropertyNamingStrategyConstant.class) * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    private <T> List<T> searchAll(String[] indices, String[] types, SearchSourceBuilder searchSourceBuilder, RequestOptions options, Class<T> tClass, Integer propertyNamingStrategy) throws IOException { 
    List<T> allList = new ArrayList<>(); List<T> list; // 设置分页尺寸 int from = -1 == searchSourceBuilder.from() ? 0 : searchSourceBuilder.from(), size = -1 == searchSourceBuilder.size() ? 5000 : searchSourceBuilder.size(), page = 0; do { 
    // 组装查询条件 SearchRequest searchRequest = new SearchRequest().indices(indices); // 类型名称不为空时,才组装type if (types != null && types.length > 0) { 
    searchRequest.types(types); } searchRequest.source(searchSourceBuilder.from(from).size(size)); SearchResponse searchResponse = client.search(searchRequest, options); SearchHits searchHits = searchResponse.getHits(); SearchHit[] searchHitsHits = searchHits.getHits(); long totalHits = searchHits.getTotalHits(); // 查询结果 list = Arrays.stream(searchHitsHits).map(searchHit -> { 
    if (Constant.ORIGINAL.equals(propertyNamingStrategy)) { 
    return MapObjectUtil.originalMapParseObject(searchHit.getSourceAsMap(), tClass); } else if (Constant.UNDERSCORE_TO_CAMEL.equals(propertyNamingStrategy)) { 
    return MapObjectUtil.underscoreToCamelMapParseObject(searchHit.getSourceAsMap(), tClass); } else { 
    throw new RuntimeException("propertyNamingStrategy is not found"); } }).collect(Collectors.toList()); // 将查询结果投入allList allList.addAll(list); // 当命中小于分页尺寸时直接跳出 if (totalHits < size) { 
    break; } // 翻页 page++; from = (page + 1) * size; // 查询直到分页的数据为null } while (!CollectionUtils.isEmpty(list)); return allList; } / * 查询全量(其实也是分页循环查询) * * @param indices 索引名称,多个时逗号分隔 * @param searchSourceBuilder 查询的builder * @param options 请求类型 * @param tClass 返回对象的类 * @param propertyNamingStrategy 转换策略(PropertyNamingStrategyConstant.class) * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    public <T> List<T> searchAll(@NonNull String indices, @NonNull SearchSourceBuilder searchSourceBuilder, @NonNull RequestOptions options, @NonNull Class<T> tClass, Integer propertyNamingStrategy) throws IOException { 
    String[] indexArray = indices.split(COMMA_SEPARATE); Objects.requireNonNull(indices, "indices must not be null"); for (String index : indexArray) { 
    Objects.requireNonNull(index, "index must not be null"); } if (Constant.ORIGINAL.equals(propertyNamingStrategy)) { 
    } else if (Constant.UNDERSCORE_TO_CAMEL.equals(propertyNamingStrategy)) { 
    } else { 
    throw new RuntimeException("propertyNamingStrategy is not found"); } return searchAll(indexArray, null, searchSourceBuilder, options, tClass, propertyNamingStrategy); } / * 查询全量(其实也是分页循环查询) * * @param searchAllBuilder 查询所有的builder * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    @Override public <T> List<T> searchAll(SearchAllBuilder searchAllBuilder, Class<T> rClass) throws IOException { 
    // 无types的查询 if (Objects.isNull(searchAllBuilder.getTypes())) { 
    return this.searchAll(searchAllBuilder.getIndices(), searchAllBuilder.getSearchSourceBuilder(), searchAllBuilder.getOptions(), rClass, searchAllBuilder.getPropertyNamingStrategy()); } return this.searchAll(searchAllBuilder.getIndices(), searchAllBuilder.getTypes(), searchAllBuilder.getSearchSourceBuilder(), searchAllBuilder.getOptions(), rClass, searchAllBuilder.getPropertyNamingStrategy()); } / * 同一个字段条件查询 * 例如:orderSn["2033-SHEN-AA","2033-SHEN-CC","2033-SHEN-BB"] * * @param indexName 索引名称 * @param field 字段名称 * @param value 字段值 * @param rClass 返回对象的类 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ @Override public <T> List<T> searchField(@NonNull String indexName, @NonNull String field, Object[] value, Class<T> rClass) throws IOException { 
    SearchSourceBuilder builder = new SearchSourceBuilder() .query(QueryBuilders.termsQuery(field, value)); SearchAllBuilder searchAllBuilder = new SearchAllBuilder() .indices(indexName) .searchSourceBuilder(builder) .propertyNamingStrategy(Constant.UNDERSCORE_TO_CAMEL); List<T> searchField = searchAll(searchAllBuilder, rClass); return searchField; } / * 多条件查询 - 【精确匹配】 * * @param indexName 索引名称 * @param queryInfo 查询条件 - 用 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); 查询 * @param rClass 返回对象的类 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ @Override public <T> List<T> searchMultipleEq(@NonNull String indexName, @NonNull HashMap<String, Object> queryInfo, Class<T> rClass) throws IOException { 
    SearchSourceBuilder builder = new SearchSourceBuilder(); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 循环添加查询条件 if (CollectionUtil.isNotEmpty(queryInfo)) { 
    for (Map.Entry<String, Object> entry : queryInfo.entrySet()) { 
    String key = entry.getKey(); Object value = entry.getValue(); queryBuilder.must(QueryBuilders.termQuery(key, value)); } } builder.query(queryBuilder); SearchAllBuilder searchAllBuilder = new SearchAllBuilder() .indices(indexName) .searchSourceBuilder(builder) .propertyNamingStrategy(Constant.UNDERSCORE_TO_CAMEL); List<T> searchField = searchAll(searchAllBuilder, rClass); return searchField; } / * 自定义查询条件 * * @param indexName 索引名称 * @param builder 查询条件封装 * @param rClass 返回对象的类 * @param 
   
     泛型 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ 
    @Override public <T> List<T> search(@NonNull String indexName, @NonNull SearchSourceBuilder builder, Class<T> rClass) throws IOException { 
    SearchAllBuilder searchAllBuilder = new SearchAllBuilder() .indices(indexName) .searchSourceBuilder(builder) .propertyNamingStrategy(Constant.UNDERSCORE_TO_CAMEL); List<T> searchField = searchAll(searchAllBuilder, rClass); return searchField; } / * 多条件查询 - 【模糊匹配】 * * @param indexName 索引名称 * @param queryInfo 查询条件 * @param rClass 返回对象的类 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ @Override public <T> List<T> searchMultipleLike(@NonNull String indexName, HashMap<String, Object> queryInfo, Class<T> rClass) throws IOException { 
    SearchSourceBuilder builder = new SearchSourceBuilder(); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 循环添加查询条件 if (CollectionUtil.isNotEmpty(queryInfo)) { 
    for (Map.Entry<String, Object> entry : queryInfo.entrySet()) { 
    String key = entry.getKey(); String value = String.valueOf(entry.getValue()); queryBuilder.must(QueryBuilders.wildcardQuery(key, value)); } } builder.query(queryBuilder); SearchAllBuilder searchAllBuilder = new SearchAllBuilder() .indices(indexName) .searchSourceBuilder(builder) .propertyNamingStrategy(Constant.UNDERSCORE_TO_CAMEL); List<T> searchField = searchAll(searchAllBuilder, rClass); return searchField; } / * 修改 * * @param indexName 索引名称 * @param type 类型 * @param id id * @param updateData 修改的字段和值 * @return 更新成功记录数 * @throws IOException 抛出io异常 */ @Override public Boolean update(@NonNull String indexName, @NonNull String type, @NonNull String id, HashMap<String, Object> updateData) throws IOException { 
    UpdateRequest request = new UpdateRequest(); // 索引名称 request.index(indexName); request.id(id); // 超时时间 request.timeout(TimeValue.timeValueSeconds(10)); / * ----------设置ES插入后的刷新策略------------ * * RefreshPolicy #IMMEDIATE: * 请求向ElasticSearch提交了数据,立即进行数据刷新,然后再结束请求。 * 优点:实时性高、操作延时短。 * 缺点:资源消耗高。 * RefreshPolicy #WAIT_UNTIL: * 请求向ElasticSearch提交了数据,等待数据完成刷新,然后再结束请求。 * 优点:实时性高、操作延时长。 * 缺点:资源消耗低。 * RefreshPolicy #NONE: * 默认策略。 * 请求向ElasticSearch提交了数据,不关系数据是否已经完成刷新,直接结束请求。 * 优点:操作延时短、资源消耗低。 * 缺点:实时性低。 */ //修改后立即刷新 request.setRefreshPolicy(RefreshPolicy.IMMEDIATE); request.type(type); request.doc(updateData); UpdateResponse response = client.update(request, RequestOptions.DEFAULT); return response.status().equals(RestStatus.OK); } / * 修改 * * @param indexName 索引名称 * @param type 类型 * @param id id * @param updateData 修改的对象 * @return 更新成功记录数 * @throws IOException 抛出io异常 */ @Override public Boolean update(@NonNull String indexName, @NonNull String type, @NonNull String id, Object updateData) throws IOException { 
    UpdateRequest request = new UpdateRequest(); // 索引名称 request.index(indexName); request.id(id); // 超时时间 request.timeout(TimeValue.timeValueSeconds(10)); //修改后立即刷新 request.setRefreshPolicy(RefreshPolicy.IMMEDIATE); request.type(type); request.doc(JSON.toJSONString(updateData), XContentType.JSON); UpdateResponse response = client.update(request, RequestOptions.DEFAULT); return response.status().equals(RestStatus.OK); } @Override public <T> SearchTermDTO searchTerm(SearchAllBuilder searchAllBuilder,String termName, Class<T> rClass) throws IOException { 
    SearchTermDTO searchTermDTO = new SearchTermDTO(); SearchSourceBuilder searchSourceBuilder = searchAllBuilder.getSearchSourceBuilder(); // 设置分页尺寸 int from = -1 == searchSourceBuilder.from() ? 0 : searchSourceBuilder.from(), size = -1 == searchSourceBuilder.size() ? 5000 : searchSourceBuilder.size(), page = 0; List<T> allList = new ArrayList<>(); List<Terms.Bucket> buckets = CollectionUtil.newArrayList(); List<T> list; do { 
    // 组装查询条件 SearchRequest searchRequest = new SearchRequest().indices(searchAllBuilder.getIndices()); // 类型名称不为空时,才组装type if (searchAllBuilder.getTypes() != null) { 
    String[] typeArray = searchAllBuilder.getTypes().split(COMMA_SEPARATE); searchRequest.types(typeArray); } searchRequest.source(searchSourceBuilder.from(from).size(size)); SearchResponse searchResponse = client.search(searchRequest, searchAllBuilder.getOptions()); Aggregations aggregations = searchResponse.getAggregations(); Terms terms = aggregations.get(termName); List<? extends Terms.Bucket> termsBuckets = terms.getBuckets(); for (Terms.Bucket bucket : termsBuckets) { 
    buckets.add(bucket); } SearchHits searchHits = searchResponse.getHits(); SearchHit[] searchHitsHits = searchHits.getHits(); long totalHits = searchHits.getTotalHits(); // 查询结果 list = Arrays.stream(searchHitsHits).map(searchHit -> { 
    if (Constant.ORIGINAL.equals(searchAllBuilder.getPropertyNamingStrategy())) { 
    return MapObjectUtil.originalMapParseObject(searchHit.getSourceAsMap(), rClass); } else if (Constant.UNDERSCORE_TO_CAMEL.equals(searchAllBuilder.getPropertyNamingStrategy())) { 
    return MapObjectUtil.underscoreToCamelMapParseObject(searchHit.getSourceAsMap(), rClass); } else { 
    throw new RuntimeException("propertyNamingStrategy is not found"); } }).collect(Collectors.toList()); // 将查询结果投入allList allList.addAll(list); // 当命中小于分页尺寸时直接跳出 if (totalHits < size) { 
    break; } // 翻页 page++; from = (page + 1) * size; // 查询直到分页的数据为null } while (!CollectionUtils.isEmpty(list)); searchTermDTO.setResultList(allList); searchTermDTO.setBuckets(buckets); return searchTermDTO; } / * 指定字段查询 * * @param indexName 索引名称 * @param field 字段名称 * @param value 字段值 * @param rClass 返回对象的类 * @return 返回查询出来的全量数据 * @throws IOException 抛出io异常 */ @Override public <T> T searchField(String indexName, String field, Object value, Class<T> rClass) throws IOException { 
    SearchSourceBuilder builder = new SearchSourceBuilder() .query(QueryBuilders.termQuery(field, value)); SearchAllBuilder searchAllBuilder = new SearchAllBuilder() .indices(indexName) .searchSourceBuilder(builder) .propertyNamingStrategy(Constant.UNDERSCORE_TO_CAMEL); List<T> searchField = searchAll(searchAllBuilder, rClass); return searchField.get(Constant.ZERO); } } 

7、map对象转换工具类

/ * map对象转换工具类 * * @author Lance * @version 1.0 * @data 2022/03/24 23:25 */ @Component public class MapObjectUtil { 
    / * 将下划线key驼峰化的map转为原生object对象 * * @param map * @param beanClass * @param 
   
     * @return */ 
    public static <T> T underscoreToCamelMapParseObject(Map<String, Object> map, Class<T> beanClass) { 
    if (map == null) { 
    return null; } try { 
    // 下划线转驼峰 SerializeConfig config = new SerializeConfig(); config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; return JSON.parseObject(JSON.toJSONString(map, config), beanClass); } catch (Exception e) { 
    throw new RuntimeException(e); } } / * 将es原始key的map转为原生object对象 * * @param map * @param beanClass * @param 
   
     * @return */ 
    public static <T> T originalMapParseObject(Map<String, Object> map, Class<T> beanClass) { 
    if (map == null) { 
    return null; } try { 
    return JSON.parseObject(JSON.toJSONString(map), beanClass); } catch (Exception e) { 
    throw new RuntimeException(e); } } / * 将对象转为map * * @param obj * @return */ public static Map<String, Object> objectParseMap(Object obj) { 
    if (obj == null) { 
    return null; } return ((JSONObject) JSON.toJSON(obj)).getInnerMap(); } } 

8、测试调用

 @GetMapping("mall/tracking/number") @ApiOperation("多条件查询") @Override public List<PddElasticOrderVo> findByMallIdAndTrackingNumber(Long mallId, String trackingNumber) { 
    // Vo 里面的字段一定要和 ES 中的字段一一对应 // 可以将 ES 中的json 在线生成javaBean List<PddElasticOrderVo> orderList = new ArrayList<>(); // 精确匹配查询条件 HashMap<String, Object> queryInfo = new HashMap<>(); queryInfo.put(LambdaUtils.getfieldName(PddElasticOrderVo::getMallId), mallId); queryInfo.put(LambdaUtils.getfieldName(PddElasticOrderVo::getTrackingNumber), trackingNumber); try { 
    List<JSONObject> searchField = searchApiService.searchMultipleEq(EsConfig.ES_ORDER_INDEX, queryInfo, JSONObject.class); searchField.stream().forEach(item -> { 
    PddElasticOrderVo orderVo = item.toBean(PddElasticOrderVo.class); orderList.add(orderVo); }); log.info("ES中搜索到 {} 条数据!", orderList.size()); return orderList; } catch (IOException e) { 
    log.error(e.getMessage()); } return Collections.emptyList(); } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/209547.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午9:00
下一篇 2026年3月19日 上午9:00


相关推荐

  • 智谱推出 GLM Coding Plan 企业版:以最强 Agentic Coding 赋能千行百业

    智谱推出 GLM Coding Plan 企业版:以最强 Agentic Coding 赋能千行百业

    2026年3月12日
    2
  • 达梦(DM)4、SpringBoot集成MyBatisPlus+达梦数据库(DM)

    达梦(DM)4、SpringBoot集成MyBatisPlus+达梦数据库(DM)最近在做一个政府项目 由于项目之前使用的 MySQL 数据库 为了适配国产化 需要将 MySQL 换成达梦数据库 DM 本次我选择了达梦数据库 8 DM8 以下是切换过程一 引入达梦数据库驱动与 MySQL 同样如此 也需要驱动包来连接 MySQL 只不过 SpringBoot 对 MySQL 做了集成 没有对达梦数据库做集成 所以 我们需要自己引入驱动包 这个驱动包通过 maven 仓库是下载不了的由于我们之前是安装了达梦数据库 DM8 的 然后我们在其安装目录下是可以找到驱动包的 D dmd

    2026年3月19日
    2
  • HttpCanary下载_HTML自我介绍

    HttpCanary下载_HTML自我介绍前言首先,我们无论学习哪个框架,都要带着问题,带着思考去学习思考1:HttpRunner是什么?思考2:HttpRunner的设计模式是什么?思考3:为什么我们要学习HttpRunner?他的

    2022年7月31日
    8
  • dataTable自定义搜索框位置

    dataTable自定义搜索框位置其实不能叫自定义位置dataTable的搜索框请参阅dataTabledom:http://www.datatables.club/reference/option/dom.html我的需求是将dataTable默认位置的搜索框移动到我的form表单中的搜索位置如图:因为自己不会写前端却要写前端幸得群里大神指点在页面写样式覆盖原来的样式在这里记录一下解决办法…

    2022年7月13日
    22
  • 哈佛幸福课笔记[通俗易懂]

    哈佛幸福课笔记[通俗易懂]第一课什么是积极心理学1、快乐由精神状态决定,而不是社会地位和银行存款2、成功的两个因素:相信自己、保持好奇不断学习第二课为什么要学习积极心理学1、你所问的问题决定了你的感受,当一个人总是问自己:我的弱点是什么?我如何做的更好?他会忽略自己的优点,认为优点是不存在的2、从专注缺点到专注优点3、做一个行动者,行动可以增加自信,而不是一个被动者抱怨者第三课幸福是一…

    2022年7月25日
    15
  • 为何把2点半比作是神奇的2点半? 为什么炒股的人叫14:30分,叫神奇的2点[通俗易懂]

    为何把2点半比作是神奇的2点半? 为什么炒股的人叫14:30分,叫神奇的2点[通俗易懂]为何把14:30分称作神奇的2点半?为什么炒股的人叫14:30分,叫神奇的2点半?这个得从头开始说起!第一个是早盘:9:30-9:50,请一般散户不要参与!这是主力展示盘口语言的时间段,自认为水平

    2022年7月1日
    30

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号