elasticsearch通用工具类

博客 分享
0 250
张三
张三 2022-03-11 12:56:28
悬赏:0 积分 收藏

elasticsearch通用工具类

  这几天写了一个关于es的工具类,主要封装了业务中常用es的常用方法。

  本文中使用到的elasticsearch版本6.7,但实际上也支持es7.x以上版本,因为主要是对springboot提供的:ElasticsearchRestTemplate 提供的API做的二次封装。目的是:让不懂es的开发人员新手也能轻松上手。

一、概述

整个工程分为es-api与es-server。

es-api为对外公共jar,包含了es映射实体;

es-server包含了具体的es工具类与Repository接口(下文会提到)。并通过necos配置中心统一管理es配置参数。

外部业务模块可引入es-api jar maven依赖,由Jar提供的入口,通过httpClient或feign调用(springcloud分布式项目)到es-server服务上的es工具类,得到需要的数据。

二、使用

这里仅以springcloud分布式项目简单为例

业务方用户服务user 引入es-api maven

/** * @author: shf * description: es-server feign接口 */public interface EsServerClient {    @PostMapping(value = "/queryList", produces = {"application/json"})    public <T> List<T> queryList(@RequestBody T t);}

在user服务中创建feignClient继承自es-api中的EsServerClient

@FeignClient(contextId = "esFeignClient", name = "es-server")public interface EsFeignClient extends EsServerClient {}

在user服务的代码中即可调用

@AutoWiredpublic EsFeignClient esFeignClient;  public void test() {   //.......如业务方Dto与es映射实体转换 等省略  //....  EmployeeEs employee = new EmployeeEs();  List queryList = Stream.of(employee.new QueryRelation<String>("张三", EntityEs.SHOULD, 5F), employee.new QueryRelation<String>("李四", EntityEs.SHOULD, 20F)).collect(Collectors.toList());  employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, queryList).put(EmployeeEs::getUserAge, employee.new RangeRelation(20, EntityEs.GTE, null, null, EntityEs.MUST)));  //排序查询  employee.setOrderMap(new EsMapUtil().put(EmployeeEs::getUserId, SortOrder.DESC));  List<EmployeeEs> employeeEs = esFeignClient.queryList(employee);  //.....employeeEs与业务方Dto转换}

三、具体实现

es-api 引入es依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>    <exclusions>        <exclusion>            <groupId>org.elasticsearch.client</groupId>            <artifactId>transport</artifactId>        </exclusion>        <exclusion>            <groupId>org.elasticsearch.client</groupId>            <artifactId>elasticsearch-rest-high-level-client</artifactId>        </exclusion>    </exclusions></dependency><dependency>    <groupId>org.elasticsearch.client</groupId>    <artifactId>transport</artifactId>    <version>6.7.0</version></dependency><dependency>    <groupId>org.elasticsearch.client</groupId>    <artifactId>elasticsearch-rest-high-level-client</artifactId>    <version>6.7.0</version></dependency>

排除后重新引入对应的Es版本6.7,避免因版本不一致导致的一些坑。

es-server 服务 application.yml配置es

spring: elasticsearch:  rest:    #ES的连接地址,多个地址用逗号分隔    uris: localhost:9200    username: kibana    password: pass    #连接超时时间    connection-timeout: 1000    #读取超时时间    read-timeout: 1000

一、映射实体

1、与ES mapping结构对应的映射实体:EmployeeEs

说明:

①设置的字段与该es对应的该索引完全对应,不存在多余字段。

②项目中引入了spring-boot-starter-data-elasticsearch,所以可直接使用注解形式设置索引信息与mapping结构信息,详见示例

③@JsonIgnoreProperties({"orderMap","pageNumber","pageSize","highlightFields","preTags","postTags","fieldQueryMap","scrollId","aggregationMap","multiLayerQueryList"})

    作用:在保存文档到es时忽略父类EntityEs中的功能性字段,下文会提到

④@EsRepository(EmployeeEsRepository.class)

    作用:通过注解过去该映射对应的Repository接口

/** * 员工对象 * <p> * 注解:@Document用来声明Java对象与ElasticSearch索引的关系 indexName 索引名称 type 索引类型 shards 主分区数量,默认5 * replicas 副本分区数量,默认1 createIndex 索引不存在时,是否自动创建索引,默认true */@Setter@Getter@Builder@AllArgsConstructor@NoArgsConstructor@EsRepository(EmployeeEsRepository.class)@JsonIgnoreProperties({"orderMap","pageNumber","pageSize","highlightFields","preTags","postTags","fieldQueryMap","scrollId","aggregationMap","multiLayerQueryList"})@Document(indexName = "employee_index", type = "employee_type", shards = 1, replicas = 0, createIndex = true)public class EmployeeEs extends EntityEs {  @Id @Field(type = FieldType.Keyword)    private Long userId;  //@Field(type = FieldType.Text, analyzer = "ik_max_word") @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "ik_max_word"), otherFields = @InnerField(suffix = "trueName", type = FieldType.Keyword))    private String userName;  @Field(type = FieldType.Keyword)    private String userCode;  @Field(type = FieldType.Integer)    private Integer userAge;  @Field(type = FieldType.Keyword)    private String userMobile;  @Field(type = FieldType.Date)    private Date birthDay;  @Field(type = FieldType.Keyword) private String userSex;   @Field(type = FieldType.Text, analyzer = "ik_max_word")    private String remarks;}
View Code

2、Repository接口:EmployeeEsRepository 

/** * @author: shf * description: 可根据映射实体设置自动生成mapping结构;支持bean的增删改查操作 * date: 2022/2/23 10:47 */@Componentpublic interface EmployeeEsRepository extends CrudRepository<EmployeeEs,Long> {}

二、功能性实体类:EntityEs

说明:

①所有字段非es索引中的mapping属性字段,均为功能性字段,如排序、高亮、分页设置和一些常量设置等,详见贴码

②所有es映射实体类均需继承该实体

/** * @author: shf description: 功能性字段(非mapping结构字段) * date: 2022/3/1 15:07 */@Datapublic class EntityEs {    /**     * 组合多查询常量     */    /**     * 文档 必须 匹配这些条件才能被查询到。相当于sql中的and     */    public static String MUST = "must";    /**     * 文档 必须不 匹配这些条件才能被查询到。相当于sql中的 not     */    public static String MUST_NOT = "must_not";    /**     * 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。相当于sql中的or     */    public static String SHOULD = "should";    /**     * 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档     */    public static String FILTER = "filter";    /**     * 至少匹配一项should子句     */    public static String MINIMUM_SHOULD_MATCH = "minimum_should_match";    /**     * 多字段排序查询     */    public EsMapUtil orderMap;    /**     * 分页查询     */    public Integer pageNumber;    public Integer pageSize;    /**     * 游标分页ID     */    public String scrollId;    /**     * 游标分页ID有效期 单位:毫秒     */    public static Long scrollIdExpireTime = 1000 * 60 * 2L;    /**     * 游标分页ID最小有效期 单位:毫秒     */    public static Long scrollIdMinExpireTime = 1000L;    /**     * 高亮查询     */    public List<String> highlightFields;    public String preTags;    public String postTags;    /**     * 字段查询     */    public EsMapUtil fieldQueryMap;    /**     * 聚合查询,当前只支持单个字段分组聚合count与sum,只针对keyword类型字段有效     */    public EsMapUtil aggregationMap;    public static String COUNT = "count";    public static String SUM = "sum";    /**     * 多层(bool)查询     */    public List multiLayerQueryList;    /**     * 范围查询常量     */    public static String GT = "gt";    public static String GTE = "gte";    public static String LT = "lt";    public static String LTE = "lte";    @Data    public class RangeRelation<T> {        //String fieldKey;        T fieldMinValue;        String fieldMinMode;        T fieldMaxValue;        String fieldMaxMode;        String queryMode;        public RangeRelation(T fieldMinValue, String fieldMinMode, T fieldMaxValue, String fieldMaxMode, String queryMode) {            this.fieldMinValue = fieldMinValue;            this.fieldMinMode = fieldMinMode;            this.fieldMaxValue = fieldMaxValue;            this.fieldMaxMode = fieldMaxMode;            this.queryMode = queryMode;        }    }    @Data    public class QueryRelation<T> {        T fieldValue;        String queryMode;        Float boostValue;        public QueryRelation(T fieldValue, String queryMode) {            this.fieldValue = fieldValue;            this.queryMode = queryMode;        }        public QueryRelation(T fieldValue, String queryMode, Float boostValue) {            this.fieldValue = fieldValue;            this.queryMode = queryMode;            this.boostValue = boostValue;        }    }    @Data    public class MultiLayerRelation {        String queryMode;        EsMapUtil map;        List<EntityEs.MultiLayerRelation> multiLayerList;        public MultiLayerRelation(String queryMode, EsMapUtil map) {            this.queryMode = queryMode;            this.map = map;        }        public MultiLayerRelation(String queryMode, EsMapUtil map, List<MultiLayerRelation> multiLayerList) {            this.queryMode = queryMode;            this.map = map;            this.multiLayerList = multiLayerList;        }    }}
View Code

三、小工具:EsMapUtil

说明:封装了一个map工具,编码简洁链式调用,应用了方法引用特性避免了字符串硬编码造成单词拼错的情况。

/** * @author: shf description: 函数式接口 便于方法引用获取实体字段名称 * date: 2022/3/4 13:41 */@FunctionalInterfacepublic interface IGetterFunction<T> extends Serializable{    Object get(T source);}
/** * @author: shf * description * date: 2019/11/13 18:30 */public class EsMapUtil extends LinkedHashMap<String, Object> {    public <T> EsMapUtil put(IGetterFunction<T> fn, Object value) {        String key = getFieldName(fn);        super.put(key, value);        return this;    }    public <T> EsMapUtil putStr(String key, Object value) {        super.put(key, value);        return this;    }    private static Map<Class, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();    /***     * 转换方法引用为属性名     * @param fn     * @return     */    public <T> String getFieldName(IGetterFunction<T> fn) {        SerializedLambda lambda = getSerializedLambda(fn);        String methodName = lambda.getImplMethodName();        String prefix = null;        if (methodName.startsWith("get")) {            prefix = "get";        }        // 截取get之后的字符串并转换首字母为小写        return toLowerCaseFirstOne(methodName.replace(prefix, ""));    }    /**     * 首字母转小写     *     * @param s     */    public String toLowerCaseFirstOne(String s) {        if (Character.isLowerCase(s.charAt(0))) {            return s;        } else {            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();        }    }    public static SerializedLambda getSerializedLambda(Serializable fn) {        SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());        if (lambda == null) {            try {                Method method = fn.getClass().getDeclaredMethod("writeReplace");                method.setAccessible(Boolean.TRUE);                lambda = (SerializedLambda) method.invoke(fn);                CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);            } catch (Exception e) {                e.printStackTrace();            }        }        return lambda;    }}
View Code

四、Es通用工具类EsService

/** * @author: shf description: es工具类,支持:分页(支持游标分页)、高亮(支持自定义标签)、范围查找、bool组合查询、多层bool套bool、多字段排序、加权重、聚合、二级字段查询 * date: 2022/2/23 10:54 */@Component@Slf4jpublic class EsService {    @Autowired    private ElasticsearchRestTemplate restTemplate;     @Autowired    private ApplicationContext context;      /**     * 判断索引是否存在     *     * @return boolean     */    public <T> boolean indexExists(Class<T> clazz) {        return restTemplate.indexExists(clazz);    }     /**     * 判断索引是否存在     *     * @param indexName 索引名称     * @return boolean     */    public boolean indexExists(String indexName) {        return restTemplate.indexExists(indexName);    }     /**     * 创建索引(推荐使用:因为Java对象已经通过注解描述了Setting和Mapping)     *     * @return boolean     */    public <T> boolean indexCreate(Class<T> clazz) {        boolean createFlag = restTemplate.createIndex(clazz);        boolean mappingFlag = restTemplate.putMapping(clazz);        return createFlag && mappingFlag;     }     /**     * 索引删除     *     * @param indexName 索引名称     * @return boolean     */    public boolean indexDelete(String indexName) {        return restTemplate.deleteIndex(indexName);    }     /**     * 新增数据     *     * @param bean 数据对象     */    public <T> void saveBean(T bean) {        EsRepository esRepositoryAnno = bean.getClass().getAnnotation(EsRepository.class);        CrudRepository crudRepository = (CrudRepository) context.getBean(esRepositoryAnno.value());        crudRepository.save(bean);    }     /**     * 批量新增数据     *     * @param list 数据集合     */    public <T> void saveList(List<T> list) {        if (CollectionUtils.isEmpty(list)) {            return;        }        EsRepository esRepositoryAnno = list.get(0).getClass().getAnnotation(EsRepository.class);        CrudRepository crudRepository = (CrudRepository) context.getBean(esRepositoryAnno.value());        crudRepository.saveAll(list);    }     /**     * 根据对象删除数据,主键ID不能为空     *     * @param bean 对象     */    public <T> void deleteByBean(T bean) {        EsRepository esRepositoryAnno = bean.getClass().getAnnotation(EsRepository.class);        CrudRepository crudRepository = (CrudRepository) context.getBean(esRepositoryAnno.value());        crudRepository.delete(bean);    }     /**     * 根据对象集合,批量删除     *     * @param beanList 对象集合     */    public <T> void deleteAllByBeanList(List<T> beanList) {        if (CollectionUtils.isEmpty(beanList)) {            return;        }        EsRepository esRepositoryAnno = beanList.get(0).getClass().getAnnotation(EsRepository.class);        CrudRepository crudRepository = (CrudRepository) context.getBean(esRepositoryAnno.value());        crudRepository.deleteAll(beanList);    }     /**     * 删除所有     */    public <T> void deleteAll(T bean) {        EsRepository esRepositoryAnno = bean.getClass().getAnnotation(EsRepository.class);        CrudRepository crudRepository = (CrudRepository) context.getBean(esRepositoryAnno.value());        crudRepository.deleteAll();    }     /**     * 修改数据     *     * @param t 修改数据对象,ID不能为空     */    public <T> boolean updateByBean(T t) throws IllegalAccessException {        Class clazz = t.getClass();        Field[] Fields = clazz.getDeclaredFields();        String beanId = null;        String beanIdName = null;        for (Field f : Fields) {            f.setAccessible(true);            if (f.isAnnotationPresent(org.springframework.data.annotation.Id.class)) {                beanId = String.valueOf(f.get(t));                beanIdName = f.getName();            }        }        if (StringUtils.isBlank(beanId)) {            log.warn("id不能为空");            return false;        }        if (Objects.isNull(restTemplate.queryForObject(GetQuery.getById(beanId), clazz))) {            log.warn("该文档不存在");            return false;        }        Document annotation = (Document) clazz.getAnnotation(Document.class);        UpdateRequest updateRequest = new UpdateRequest();        //冲突重试        updateRequest.retryOnConflict(1);        updateRequest.doc(JSON.toJSONString(t), XContentType.JSON);        //默认是_id来路由的,用来路由到不同的shard,会对这个值做hash,然后映射到shard。所以分片        updateRequest.routing(beanId);        UpdateQuery query = new UpdateQueryBuilder().withIndexName(annotation.indexName()).withType(annotation.type()).withId(beanId)            .withDoUpsert(false)//不加默认false。true表示更新时不存在就插入            .withClass(clazz).withUpdateRequest(updateRequest).build();        UpdateResponse updateResponse = restTemplate.update(query);        if (!Objects.equals(updateResponse.getShardInfo().getSuccessful(), 1)) {            return false;        }        return true;    }     /**     * 根据bean ID 查询     *     * @param beanId     * @param clazz     * @param <T>     */    public <T> T queryBeanById(String beanId, Class<T> clazz) {        return restTemplate.queryForObject(GetQuery.getById(beanId), clazz);    }     /**     * 数据查询,返回List     *     * @return List<T>     */    public <T> List<T> queryList(T t) throws IllegalAccessException, NoSuchFieldException {        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();        Class clazz = (Class) t.getClass();        Map<String, Object> queryMap = (LinkedHashMap) clazz.getField("fieldQueryMap").get(t);        Map<String, String> orderMap = (LinkedHashMap) clazz.getField("orderMap").get(t);        List<String> highlightFields = (List<String>) clazz.getField("highlightFields").get(t);        String preTags = StringUtils.isNotBlank((String) clazz.getField("preTags").get(t)) ? (String) clazz.getField("preTags").get(t) : "<em>";        String postTags = StringUtils.isNotBlank((String) clazz.getField("postTags").get(t)) ? (String) clazz.getField("postTags").get(t) : "</em>";        List<EntityEs.MultiLayerRelation> multiLayerQueryList = (List<EntityEs.MultiLayerRelation>) clazz.getField("multiLayerQueryList").get(t);         String beanIdName = null;        Field[] Fields = clazz.getDeclaredFields();        for (Field f : Fields) {            f.setAccessible(true);            if (f.isAnnotationPresent(org.springframework.data.annotation.Id.class)) {                beanIdName = f.getName();                break;            }        }        //构建组合查询(支持权重)        getFieldQueryBuilder(boolQueryBuilder, clazz, queryMap);        //处理多层bool查询        getNestQueryBuilder(boolQueryBuilder, clazz, multiLayerQueryList);         log.info("打印语句:{}", boolQueryBuilder.toString());        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);        //支持多字段排序查询        getOrderBuilder(beanIdName, orderMap, nativeSearchQueryBuilder);        //支持多字段高亮查询并可自定义高亮标签规则        getHighLightBuilder(highlightFields, preTags, postTags, nativeSearchQueryBuilder);         if (CollectionUtils.isEmpty(highlightFields)) {            return restTemplate.queryForList(nativeSearchQueryBuilder.build(), clazz);        } else {            nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 10000));            ScrolledPage page = restTemplate.startScroll(EntityEs.scrollIdMinExpireTime, nativeSearchQueryBuilder.build(), clazz, new SearchResultMapper() {                @Override                public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {                    List<T> chunk = new ArrayList<>();                    for (SearchHit searchHit : response.getHits()) {                        if (response.getHits().getHits().length <= 0) {                            return null;                        }                        try {                            T t = (T) JSON.parseObject(searchHit.getSourceAsString(), clazz);                            for (String fieldName : highlightFields) {                                Field f = clazz.getDeclaredField(fieldName);                                HighlightField highlightField = searchHit.getHighlightFields().get(fieldName);                                if (highlightField != null) {                                    f.setAccessible(true);                                    f.set(t, highlightField.fragments()[0].toString());                                }                            }                            chunk.add(t);                        } catch (IllegalAccessException e) {                            e.printStackTrace();                        } catch (NoSuchFieldException e) {                            e.printStackTrace();                        }                    }                    if (chunk.size() > 0) {                        return new AggregatedPageImpl<>((List<T>) chunk);                    }                    return null;                }                 @Override                public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {                    return null;                }            });            return page.toList();        }    }      /**     * 分页查询     *     * @param t     * @param <T>     */    public <T> List<T> queryPage(T t) throws IllegalAccessException, NoSuchFieldException {        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();        Class clazz = (Class) t.getClass();         Map<String, Object> queryMap = (LinkedHashMap) clazz.getField("fieldQueryMap").get(t);        Map<String, String> orderMap = (LinkedHashMap) clazz.getField("orderMap").get(t);        List<String> highlightFields = (List<String>) clazz.getField("highlightFields").get(t);        String preTags = StringUtils.isNotBlank((String) clazz.getField("preTags").get(t)) ? (String) clazz.getField("preTags").get(t) : "<em>";        String postTags = StringUtils.isNotBlank((String) clazz.getField("postTags").get(t)) ? (String) clazz.getField("postTags").get(t) : "</em>";        Integer pageNumber = !Objects.isNull((Integer) clazz.getField("pageNumber").get(t)) ? (Integer) clazz.getField("pageNumber").get(t) : 0;        Integer pageSize = !Objects.isNull((Integer) clazz.getField("pageSize").get(t)) ? (Integer) clazz.getField("pageSize").get(t) : 10;        List<EntityEs.MultiLayerRelation> multiLayerQueryList = (List<EntityEs.MultiLayerRelation>) clazz.getField("multiLayerQueryList").get(t);         String beanIdName = null;        Field[] Fields = clazz.getDeclaredFields();        for (Field f : Fields) {            f.setAccessible(true);            if (f.isAnnotationPresent(org.springframework.data.annotation.Id.class)) {                beanIdName = f.getName();                break;            }        }        //构建组合查询(支持权重)        getFieldQueryBuilder(boolQueryBuilder, clazz, queryMap);        //处理多层bool查询        getNestQueryBuilder(boolQueryBuilder, clazz, multiLayerQueryList);        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);        //支持多字段排序查询        getOrderBuilder(beanIdName, orderMap, nativeSearchQueryBuilder);        //支持多字段高亮查询并可自定义高亮标签规则        getHighLightBuilder(highlightFields, preTags, postTags, nativeSearchQueryBuilder);        //分页查询        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNumber, pageSize));         AggregatedPage page = null;        if (CollectionUtils.isEmpty(highlightFields)) {            page = restTemplate.queryForPage(nativeSearchQueryBuilder.build(), clazz);        } else {            page = restTemplate.queryForPage(nativeSearchQueryBuilder.build(), clazz, new SearchResultMapper() {                @Override                public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {                    List<T> chunk = new ArrayList<>();                    for (SearchHit searchHit : response.getHits()) {                        if (response.getHits().getHits().length <= 0) {                            return null;                        }                        try {                            T t = (T) JSON.parseObject(searchHit.getSourceAsString(), clazz);                            for (String fieldName : highlightFields) {                                Field f = clazz.getDeclaredField(fieldName);                                HighlightField highlightField = searchHit.getHighlightFields().get(fieldName);                                if (highlightField != null) {                                    f.setAccessible(true);                                    f.set(t, highlightField.fragments()[0].toString());                                }                            }                            chunk.add(t);                        } catch (IllegalAccessException e) {                            e.printStackTrace();                        } catch (NoSuchFieldException e) {                            e.printStackTrace();                        }                    }                    if (chunk.size() > 0) {                        return new AggregatedPageImpl<>((List<T>) chunk);                    }                      return null;                }                 @Override                public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {                    return null;                }            });        }        // 总记录数        long totalElements = page.getTotalElements();        // 总页数        int totalPages = page.getTotalPages();        // 当前页号        //int currentPage = page.getPageable().getPageNumber();        // 当前页数据集        List<T> beanList = page.toList();        List<T> content = page.getContent();        System.out.println(beanList);        //TODO 根据项目中的分页封装类将以上数据设置后返回即可        return Lists.newArrayList();    }      /**     * 游标分页     *     * @param t     * @param <T>     */    public <T> List<T> queryScrollPage(T t) throws IllegalAccessException, NoSuchFieldException {        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();        Class clazz = (Class) t.getClass();        String scrollId = (String) clazz.getField("scrollId").get(t);        if (StringUtils.isNotBlank(scrollId)) {            ScrolledPage page = restTemplate.continueScroll(scrollId, EntityEs.scrollIdExpireTime, clazz);            // 总记录数            long totalElements = page.getTotalElements();            // 总页数            //int totalPages = page.getTotalPages();            // 当前页号            //int currentPage = page.getPageable().getPageNumber();            // 当前页数据集            List<T> beanSet = page.toList();            List<T> content = page.getContent();            System.out.println("page.getScrollId:" + page.getScrollId());            System.out.println(beanSet);            //TODO 根据项目中的分页封装类将以上数据设置后返回即可            return Lists.newArrayList();        }        Map<String, Object> queryMap = (LinkedHashMap) clazz.getField("fieldQueryMap").get(t);        Map<String, String> orderMap = (LinkedHashMap) clazz.getField("orderMap").get(t);        List<String> highlightFields = (List<String>) clazz.getField("highlightFields").get(t);        String preTags = StringUtils.isNotBlank((String) clazz.getField("preTags").get(t)) ? (String) clazz.getField("preTags").get(t) : "<em>";        String postTags = StringUtils.isNotBlank((String) clazz.getField("postTags").get(t)) ? (String) clazz.getField("postTags").get(t) : "</em>";        Integer pageNumber = !Objects.isNull((Integer) clazz.getField("pageNumber").get(t)) ? (Integer) clazz.getField("pageNumber").get(t) : 0;        Integer pageSize = !Objects.isNull((Integer) clazz.getField("pageSize").get(t)) ? (Integer) clazz.getField("pageSize").get(t) : 10;        List<EntityEs.MultiLayerRelation> multiLayerQueryList = (List<EntityEs.MultiLayerRelation>) clazz.getField("multiLayerQueryList").get(t);         String beanIdName = null;        Field[] Fields = clazz.getDeclaredFields();        for (Field f : Fields) {            f.setAccessible(true);            if (f.isAnnotationPresent(org.springframework.data.annotation.Id.class)) {                beanIdName = f.getName();                break;            }        }        //构建组合查询(支持权重)        getFieldQueryBuilder(boolQueryBuilder, clazz, queryMap);        //处理多层bool查询        getNestQueryBuilder(boolQueryBuilder, clazz, multiLayerQueryList);        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);        //支持多字段排序查询        getOrderBuilder(beanIdName, orderMap, nativeSearchQueryBuilder);        //支持多字段高亮查询并可自定义高亮标签规则        getHighLightBuilder(highlightFields, preTags, postTags, nativeSearchQueryBuilder);        //分页查询        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNumber, pageSize));         ScrolledPage page = restTemplate.startScroll(EntityEs.scrollIdExpireTime, nativeSearchQueryBuilder.build(), clazz, new SearchResultMapper() {            @Override            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {                List<T> chunk = new ArrayList<>();                for (SearchHit searchHit : response.getHits()) {                    if (response.getHits().getHits().length <= 0) {                        return null;                    }                    try {                        T t = (T) JSON.parseObject(searchHit.getSourceAsString(), clazz);                        for (String fieldName : highlightFields) {                            Field f = clazz.getDeclaredField(fieldName);                            HighlightField highlightField = searchHit.getHighlightFields().get(fieldName);                            if (highlightField != null) {                                f.setAccessible(true);                                f.set(t, highlightField.fragments()[0].toString());                            }                        }                        chunk.add(t);                    } catch (IllegalAccessException e) {                        e.printStackTrace();                    } catch (NoSuchFieldException e) {                        e.printStackTrace();                    }                }                if (chunk.size() > 0) {                    return new AggregatedPageImpl<>((List<T>) chunk);                }                return null;            }             @Override            public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {                return null;            }        });         // 总记录数        long totalElements = page.getTotalElements();        // 总页数        //int totalPages = page.getTotalPages();        // 当前页号        //int currentPage = page.getPageable().getPageNumber();        // 当前页数据集        List<T> beanSet = page.toList();        List<T> content = page.getContent();        System.out.println("page.getScrollId:" + page.getScrollId());        System.out.println(beanSet);        //TODO 根据项目中的分页封装类将以上数据设置后返回即可        return Lists.newArrayList();    }      /**     * 聚合查询     *     * @param t     * @param <T>     */    public <T> Map queryForAggregation(T t) throws IllegalAccessException, NoSuchFieldException {        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();        Class clazz = (Class) t.getClass();         Map<String, Object> queryMap = (LinkedHashMap) clazz.getField("fieldQueryMap").get(t);        Integer pageNumber = !Objects.isNull(clazz.getField("pageNumber").get(t)) ? (Integer) clazz.getField("pageNumber").get(t) : 0;        Integer pageSize = !Objects.isNull(clazz.getField("pageSize").get(t)) ? (Integer) clazz.getField("pageSize").get(t) : 1;        Map<String, String> aggregationMap = (LinkedHashMap) clazz.getField("aggregationMap").get(t);        List<EntityEs.MultiLayerRelation> multiLayerQueryList = (List<EntityEs.MultiLayerRelation>) clazz.getField("multiLayerQueryList").get(t);         //构建组合查询(支持权重)        getFieldQueryBuilder(boolQueryBuilder, clazz, queryMap);        //处理多层bool查询        getNestQueryBuilder(boolQueryBuilder, clazz, multiLayerQueryList);        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);        //分页查询        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageNumber, pageSize));         // 创建聚合查询条件        String aggKey = null;        String aggValue = null;        for (Map.Entry<String, String> entry : aggregationMap.entrySet()) {            aggKey = entry.getKey();            aggValue = entry.getValue();            if (Objects.equals(aggValue, EntityEs.COUNT)) {                TermsAggregationBuilder agg = AggregationBuilders.terms(aggKey).field(aggKey);                nativeSearchQueryBuilder.addAggregation(agg);                break;            } else if (Objects.equals(aggValue, EntityEs.SUM)) {                SumAggregationBuilder agg = AggregationBuilders.sum(aggKey).field(aggKey);                nativeSearchQueryBuilder.addAggregation(agg);                break;            }        }        AggregatedPage page = restTemplate.queryForPage(nativeSearchQueryBuilder.build(), clazz);        // 取出聚合结果        Aggregations entitiesAggregations = page.getAggregations();        Map<String, Object> retMap = new HashMap<>();        if (Objects.equals(aggValue, EntityEs.COUNT)) {            Terms terms = (Terms) entitiesAggregations.asMap().get(aggKey);            // 遍历取出聚合字段列的值,与对应的数量            for (Terms.Bucket bucket : terms.getBuckets()) {                // 聚合字段列的值                String keyAsString = bucket.getKeyAsString();                // 聚合字段对应的数量                long docCount = bucket.getDocCount();                log.info("keyAsString={},value={}", keyAsString, docCount);                retMap.put(keyAsString, docCount);            }        } else if (Objects.equals(aggValue, EntityEs.SUM)) {            Aggregation aggregation = entitiesAggregations.get(aggKey);            retMap.put(aggregation.getName(), ((ParsedSum) aggregation).getValue());        }        // 当前页数据集        List<T> beanList = page.toList();        System.out.println("当前页数据集:" + beanList);        return retMap;    }      /**     * 根据自定义查询条件批量查询     *     * @param searchQuery     * @param clazz     * @param <T>     */    public <T> List<T> queryListBySearchQuery(SearchQuery searchQuery, Class<T> clazz) {        return restTemplate.queryForList(searchQuery, clazz);    }      /*------------------------------------------- private 私有方法 ----------------------------------------------*/     private void getNestQueryBuilder(BoolQueryBuilder boolQueryBuilder, Class clazz, List<EntityEs.MultiLayerRelation> multiLayerQueryList) throws NoSuchFieldException {        if (!CollectionUtils.isEmpty(multiLayerQueryList)) {            for (EntityEs.MultiLayerRelation r : multiLayerQueryList) {                BoolQueryBuilder nestBoolQuery = QueryBuilders.boolQuery();                EsMapUtil nestMap = r.getMap();                getFieldQueryBuilder(nestBoolQuery, clazz, nestMap);                if (Objects.equals(r.getQueryMode(), EntityEs.MUST)) {                    boolQueryBuilder.must(nestBoolQuery);                } else if (Objects.equals(r.getQueryMode(), EntityEs.SHOULD)) {                    boolQueryBuilder.should(nestBoolQuery);                } else if (Objects.equals(r.getQueryMode(), EntityEs.FILTER)) {                    boolQueryBuilder.filter(nestBoolQuery);                } else if (Objects.equals(r.getQueryMode(), EntityEs.MUST_NOT)) {                    boolQueryBuilder.mustNot(nestBoolQuery);                }                //递归嵌套                if (!CollectionUtils.isEmpty(r.getMultiLayerList())) {                    //处理多层bool查询                    getNestQueryBuilder(nestBoolQuery, clazz, r.getMultiLayerList());                }            }        }    }     /**     * 构建组合查询(支持权重)     *     * @param boolQueryBuilder     * @param clazz     * @param queryMap     */    private void getFieldQueryBuilder(BoolQueryBuilder boolQueryBuilder, Class clazz, Map<String, Object> queryMap) throws NoSuchFieldException {        if (queryMap != null && queryMap.size() > 0) {            for (Map.Entry<String, Object> entry : queryMap.entrySet()) {                String k = entry.getKey();                List vList = new ArrayList();                if (entry.getValue() instanceof List) {                    vList = (ArrayList) entry.getValue();                } else {                    vList.add(entry.getValue());                }                FieldType type = null;                if (k.indexOf(".") == -1) {                    Field f = clazz.getDeclaredField(k);                    if (f.isAnnotationPresent(org.springframework.data.elasticsearch.annotations.Field.class)) {                        type = f.getAnnotation(org.springframework.data.elasticsearch.annotations.Field.class).type();                    } else if (f.isAnnotationPresent(org.springframework.data.elasticsearch.annotations.MultiField.class)) {                        type = f.getAnnotation(org.springframework.data.elasticsearch.annotations.MultiField.class).mainField().type();                    }                } else {                    //如果字段Field type定义的是Keyword,走matchQuery效果也是term精确查询                    type = FieldType.Text;                }                if (Objects.equals(type, FieldType.Text)) {                    for (Object o : vList) {                        if (o instanceof EntityEs.RangeRelation) {                            EntityEs.RangeRelation v = (EntityEs.RangeRelation) o;                            //范围查询                            getRangeBuilder(boolQueryBuilder, k, v);                        } else if (o instanceof EntityEs.QueryRelation) {                            EntityEs.QueryRelation v = (EntityEs.QueryRelation) o;                            if (Objects.equals(v.getQueryMode(), EntityEs.MUST)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.must(QueryBuilders.matchQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.must(QueryBuilders.matchQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.MUST_NOT)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.mustNot(QueryBuilders.matchQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.mustNot(QueryBuilders.matchQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.SHOULD)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.should(QueryBuilders.matchQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.should(QueryBuilders.matchQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.FILTER)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.filter(QueryBuilders.matchQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.filter(QueryBuilders.matchQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            }                        }                    }                } else if (Objects.equals(type, FieldType.Keyword)) {                    for (Object o : vList) {                        if (o instanceof EntityEs.RangeRelation) {                            EntityEs.RangeRelation v = (EntityEs.RangeRelation) o;                            //范围查询                            getRangeBuilder(boolQueryBuilder, k, v);                        } else if (o instanceof EntityEs.QueryRelation) {                            EntityEs.QueryRelation v = (EntityEs.QueryRelation) o;                            if (Objects.equals(v.getQueryMode(), EntityEs.MUST)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.must(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.must(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.MUST_NOT)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.mustNot(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.mustNot(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.SHOULD)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.should(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.should(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.FILTER)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.filter(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.filter(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            }                         }                    }                } else {                    for (Object o : vList) {                        if (o instanceof EntityEs.RangeRelation) {                            EntityEs.RangeRelation v = (EntityEs.RangeRelation) o;                            //范围查询                            getRangeBuilder(boolQueryBuilder, k, v);                        } else if (o instanceof EntityEs.QueryRelation) {                            EntityEs.QueryRelation v = (EntityEs.QueryRelation) o;                            if (Objects.equals(v.getQueryMode(), EntityEs.MUST)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.must(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.must(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.MUST_NOT)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.mustNot(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.mustNot(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.SHOULD)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.should(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.should(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            } else if (Objects.equals(v.getQueryMode(), EntityEs.FILTER)) {                                if (Objects.isNull(v.getBoostValue())) {                                    boolQueryBuilder.filter(QueryBuilders.termQuery(k, v.getFieldValue()));                                } else {                                    boolQueryBuilder.filter(QueryBuilders.termQuery(k, v.getFieldValue()).boost(v.getBoostValue()));                                }                            }                        }                    }                }            }        }    }     /**     * 构建范围查询     *     * @param boolQueryBuilder     * @param k     * @param v     */    private void getRangeBuilder(BoolQueryBuilder boolQueryBuilder, String k, EntityEs.RangeRelation v) {        if (Objects.equals(v.getQueryMode(), EntityEs.MUST)) {            if (Objects.equals(v.getFieldMinMode(), EntityEs.GT)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).gt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.GTE)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).gte(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LT)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).lt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LTE)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).lte(v.getFieldMinValue()));            }            if (Objects.equals(v.getFieldMaxMode(), EntityEs.GT)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).gt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.GTE)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).gte(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LT)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).lt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LTE)) {                boolQueryBuilder.must(QueryBuilders.rangeQuery(k).lte(v.getFieldMaxValue()));            }        } else if (Objects.equals(v.getQueryMode(), EntityEs.MUST_NOT)) {            if (Objects.equals(v.getFieldMinMode(), EntityEs.GT)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).gt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.GTE)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).gte(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LT)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).lt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LTE)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).lte(v.getFieldMinValue()));            }            if (Objects.equals(v.getFieldMaxMode(), EntityEs.GT)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).gt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.GTE)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).gte(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LT)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).lt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LTE)) {                boolQueryBuilder.mustNot(QueryBuilders.rangeQuery(k).lte(v.getFieldMaxValue()));            }        } else if (Objects.equals(v.getQueryMode(), EntityEs.SHOULD)) {            if (Objects.equals(v.getFieldMinMode(), EntityEs.GT)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).gt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.GTE)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).gte(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LT)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).lt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LTE)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).lte(v.getFieldMinValue()));            }            if (Objects.equals(v.getFieldMaxMode(), EntityEs.GT)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).gt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.GTE)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).gte(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LT)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).lt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LTE)) {                boolQueryBuilder.should(QueryBuilders.rangeQuery(k).lte(v.getFieldMaxValue()));            }        } else if (Objects.equals(v.getQueryMode(), EntityEs.FILTER)) {            if (Objects.equals(v.getFieldMinMode(), EntityEs.GT)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).gt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.GTE)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).gte(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LT)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).lt(v.getFieldMinValue()));            } else if (Objects.equals(v.getFieldMinMode(), EntityEs.LTE)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).lte(v.getFieldMinValue()));            }            if (Objects.equals(v.getFieldMaxMode(), EntityEs.GT)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).gt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.GTE)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).gte(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LT)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).lt(v.getFieldMaxValue()));            } else if (Objects.equals(v.getFieldMaxMode(), EntityEs.LTE)) {                boolQueryBuilder.filter(QueryBuilders.rangeQuery(k).lte(v.getFieldMaxValue()));            }        }     }     /**     * 构建排序查询     *     * @param beanIdName     * @param orderMap     * @param nativeSearchQueryBuilder     */    private void getOrderBuilder(String beanIdName, Map orderMap, NativeSearchQueryBuilder nativeSearchQueryBuilder) {        if (orderMap != null && orderMap.size() > 0) {            orderMap.forEach((k, v) -> {                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort((String) k).order((SortOrder) v));            });        } else {            //无指定排序字段默认按ID倒序            //nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(beanIdName).order(SortOrder.DESC));        }    }     /**     * 构建高亮查询     *     * @param highlightFields     * @param preTags     * @param postTags     * @param nativeSearchQueryBuilder     */    private void getHighLightBuilder(List<String> highlightFields, String preTags, String postTags, NativeSearchQueryBuilder nativeSearchQueryBuilder) {        if (highlightFields != null && highlightFields.size() > 0) {            List<HighlightBuilder.Field> highlightTitles = new ArrayList<>();            for (String title : highlightFields) {                highlightTitles.add(new HighlightBuilder.Field(title).preTags(preTags).postTags(postTags));            }            nativeSearchQueryBuilder.withHighlightFields(highlightTitles.stream().toArray(HighlightBuilder.Field[]::new));        }    }}
View Code

五、单元测试

1、根据映射实体设置生成索引与mapping

      说明:启动项目会自动加载自动创建,如需要手动创建可调用方法

@Testpublic void indexCreateTest() {    System.out.println(esService.indexCreate(EmployeeEs.class));}

2、删除指定索引

@Testpublic void indexDelete() {    System.out.println(esService.indexDelete("employee_index"));}

3、判断指定索引是否存在

@Testpublic void indexExists() {    System.out.println(esService.indexExists(EmployeeEs.class));}

4、保存单个bean

@Autowiredprivate EsService esService; @Testpublic void saveBean() {    System.out.println("-----es测试start..."); EmployeeEs employee = EmployeeEs.builder().userId(9L).userName("张三1").userCode("abc").userAge(22).userMobile("12345678987")        .remarks("今天天气好晴朗~").birthDay(new Date()).build(); esService.saveBean(employee); System.out.println("-----es测试end...");}

5、批量保存

@Testpublic void saveList() throws ParseException {    System.out.println("-----es测试start..."); EmployeeEs employee  =  EmployeeEs.builder().userId(1L).userName("张三").userCode("abc").userAge(18).userSex("男").userMobile("12345678987").birthDay(new SimpleDateFormat("yyyy-MM-dd").parse("1995-9-20")).build(); EmployeeEs employee1 = EmployeeEs.builder().userId(2L).userName("李四").userCode("abc").userAge(10).userSex("女").userMobile("12345678987").birthDay(new SimpleDateFormat("yyyy-MM-dd").parse("1995-6-20")).build(); EmployeeEs employee2 = EmployeeEs.builder().userId(3L).userName("王五").userCode("abc").userAge(10).userSex("男").userMobile("12345678987").birthDay(new SimpleDateFormat("yyyy-MM-dd").parse("1995-5-20")).build(); EmployeeEs employee3 = EmployeeEs.builder().userId(4L).userName("赵六").userCode("abc").userAge(20).userSex("男").userMobile("12345678987").birthDay(new SimpleDateFormat("yyyy-MM-dd").parse("1995-8-20")).build(); EmployeeEs employee4 = EmployeeEs.builder().userId(5L).userName("董七").userCode("abc").userAge(20).userSex("女").userMobile("12345678987").birthDay(new SimpleDateFormat("yyyy-MM-dd").parse("1995-8-20")).build();  esService.saveList(Lists.newArrayList(employee,employee1,employee2,employee3,employee4)); System.out.println("-----es测试end...");}

 

 

6、根据ID删除指定Bean

@Testpublic void deleteByBean() {    EmployeeEs employee = EmployeeEs.builder().userId(1L).build(); esService.deleteByBean(employee);}

7、批量删除

@Testpublic void deleteList() {    EmployeeEs employee = EmployeeEs.builder().userId(1L).build(); EmployeeEs employee1 = EmployeeEs.builder().userId(2L).build(); esService.deleteAllByBeanList(Lists.newArrayList(employee,employee1));}

8、删除该索引下所有数据

@Testpublic void deleteAll() {    esService.deleteAll(EmployeeEs.class);}

9、修改数据(ID不能为空)

@Testpublic void updateTest() throws IllegalAccessException {    System.out.println("-----es测试start..."); EmployeeEs employee = EmployeeEs.builder().userId(5L).userName("张一").userCode("abcD").userAge(19).build(); esService.updateByBean(employee); System.out.println("-----es测试end...");}

10、根据ID查询指定Bean

@Testpublic void queryById() {    EmployeeEs employeeEs = esService.queryBeanById("2", EmployeeEs.class); System.out.println(employeeEs);}

11、批量查询

/** * 涉及到了组合查询bool、权重、范围查找、排序 */@Testpublic void queryList() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start..."); EmployeeEs employee = new EmployeeEs(); List queryList = Stream.of(employee.new QueryRelation<String>("张三", EntityEs.SHOULD, 5F), employee.new QueryRelation<String>("李四", EntityEs.SHOULD, 20F)).collect(Collectors.toList()); employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, queryList).put(EmployeeEs::getUserAge, employee.new RangeRelation(20, EntityEs.GTE, null, null, EntityEs.MUST))); //排序查询 employee.setOrderMap(new EsMapUtil().put(EmployeeEs::getUserId, SortOrder.DESC)); List<EmployeeEs> employeeEs = esService.queryList(employee); System.out.println(employeeEs); System.out.println("-----es测试end...");}

打印出来的语句:

查询结果:

12、二级属性查询

@Testpublic void querySecondList() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start..."); EmployeeEs employee = new EmployeeEs(); employee.setFieldQueryMap(new EsMapUtil().putStr("userName.trueName", employee.new QueryRelation<String>("张三", EntityEs.MUST))); List<EmployeeEs> employeeEsList = esService.queryList(employee); System.out.println(employeeEsList); System.out.println("-----es测试end...");}

先准备一条测试数据插入

看下上面查询语句的结果:

由于userName的二级属性trueName的类型是keyword,所以是term精确查找

对比:

@Testpublic void querySecondList() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start..."); EmployeeEs employee = new EmployeeEs(); employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, employee.new QueryRelation<String>("张三", EntityEs.MUST))); //employee.setFieldQueryMap(new EsMapUtil().putStr("userName.trueName", employee.new QueryRelation<String>("张三", EntityEs.MUST))); List<EmployeeEs> employeeEsList = esService.queryList(employee); System.out.println(employeeEsList); System.out.println("-----es测试end...");}

13、分页查询

@Testpublic void queryPage() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start...");    EmployeeEs employee = new EmployeeEs();    List<EntityEs.QueryRelation> queryList = Stream.of(employee.new QueryRelation<String>("张三", EntityEs.SHOULD), employee.new QueryRelation<String>("李四", EntityEs.SHOULD)).collect(Collectors.toList());    employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, queryList));    //分页    employee.setPageNumber(0);    employee.setPageSize(2);    List<EmployeeEs> employeeEs = esService.queryPage(employee);    System.out.println(employeeEs);    System.out.println("-----es测试end...");}

14、游标分页查询

@Testpublic void queryScrollPage() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start...");    String scrollId = "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAADJEWMVFWMVBnb1ZSZDZsV1k2Y2JjLVlldw==";    EmployeeEs employee = new EmployeeEs();    if (StringUtils.isNotBlank(scrollId)) {        //如果前端有传scrollId        employee.setScrollId(scrollId);        List<EmployeeEs> employeeEs = esService.queryScrollPage(employee);        System.out.println(employeeEs);    } else {        List<EntityEs.QueryRelation> queryList = Stream.of(employee.new QueryRelation<String>("张三", EntityEs.SHOULD, 20F), employee.new QueryRelation<String>("李四", EntityEs.SHOULD)).collect(Collectors.toList());        employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, queryList));        //每页页数        employee.setPageSize(4);        List<EmployeeEs> employeeEs = esService.queryScrollPage(employee);        System.out.println(employeeEs);    }    System.out.println("-----es测试end...");}

15、多层bool套bool查询

@Testpublic void queryMuiltiLayer() throws IllegalAccessException, NoSuchFieldException {    System.out.println("-----es测试start...");    EmployeeEs employee = new EmployeeEs();        //多层bool查询    employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserSex, employee.new QueryRelation("男", EntityEs.MUST)));    List<EntityEs.QueryRelation> multiLayerUserAgeList = Stream.of(employee.new QueryRelation(10, EntityEs.SHOULD), employee.new QueryRelation(18, EntityEs.SHOULD)).collect(Collectors.toList());    EntityEs.MultiLayerRelation multiLayerRelation = employee.new MultiLayerRelation(EntityEs.MUST, new EsMapUtil().put(EmployeeEs::getUserAge, multiLayerUserAgeList));    employee.setMultiLayerQueryList(Lists.newArrayList(multiLayerRelation));     List<EmployeeEs> userEs = esService.queryList(employee);    System.out.println(userEs);    System.out.println("-----es测试end...");}

示例:查找年龄为10或者18岁的男性员工

//错误案例EmployeeEs employee = new EmployeeEs();List<EntityEs.QueryRelation> ageList = Lists.newArrayList(employee.new QueryRelation(10, EntityEs.SHOULD), employee.new QueryRelation(18, EntityEs.SHOULD));employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserSex, employee.new QueryRelation("男", EntityEs.MUST))    .put(EmployeeEs::getUserAge,ageList));List<EmployeeEs> userEs = esService.queryList(employee);System.out.println(userEs);

结果年龄为20的赵六也被查询了出来。原因是:当should遇到must和filter时就不是或者了,而是应该的意思。可通过must嵌套一层解决。

修改为多层bool查询

EmployeeEs employee = new EmployeeEs();//修改为多层bool查询employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserSex, employee.new QueryRelation("男", EntityEs.MUST)));List<EntityEs.QueryRelation> multiLayerUserAgeList = Stream.of(employee.new QueryRelation(10, EntityEs.SHOULD), employee.new QueryRelation(18, EntityEs.SHOULD)).collect(Collectors.toList());EntityEs.MultiLayerRelation multiLayerRelation = employee.new MultiLayerRelation(EntityEs.MUST, new EsMapUtil().put(EmployeeEs::getUserAge, multiLayerUserAgeList));employee.setMultiLayerQueryList(Lists.newArrayList(multiLayerRelation)); List<EmployeeEs> userEs = esService.queryList(employee);

 

 

16、高亮查询

@Testpublic void highlightTest() throws NoSuchFieldException, IllegalAccessException {    System.out.println("-----es测试start...");    EmployeeEs employee = new EmployeeEs();    employee.setFieldQueryMap(new EsMapUtil().put(EmployeeEs::getUserName, employee.new QueryRelation<String>("张三", EntityEs.MUST))        .put(EmployeeEs::getRemarks, employee.new QueryRelation<String>("天气", EntityEs.MUST)));    employee.setHighlightFields(Lists.newArrayList("remarks"));    //默认<em></em>,可自定义高亮标签    employee.setPreTags("<h1>");    employee.setPostTags("</h1>");    List<EmployeeEs> employeeEs = esService.queryList(employee);    System.out.println(employeeEs);    System.out.println("-----es测试end...");}

17、聚合查询

@Testpublic void queryForAggregation() throws NoSuchFieldException, IllegalAccessException {    System.out.println("-----queryForAggregation-es测试start...");    EmployeeEs employee = new EmployeeEs();    employee.setAggregationMap(new EsMapUtil().put(EmployeeEs::getUserAge, EntityEs.COUNT));    Map employeeEsAggMap = esService.queryForAggregation(employee);    System.out.println("返回结果:" + employeeEsAggMap);    System.out.println("-----queryForAggregation-es测试end...");}

将上面的EntityEs.COUNT改为EntityEs.SUM 求和运行结果:

 

posted @ 2022-03-11 11:10 奕锋博客 阅读(16) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员