Elasticsearch8搭建及Springboot中集成使用_elasticsearch8安装配置

@Target({ElemantType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ElasticSearchDocument {
   String index() default "";
   int shards() default 0;
   int replicas() default 0;
}
2.4.2.查询实体类
@Data
public class EsQueryDTO {

    private String indexName;//索引名称
    private String field;//关键字属性
    private String word;//关键字值
    private List<String> words;//关键字值数组
    private Integer from;//起始行
    private Integer index;//当前页
    private Integer size;//分页条数
    private String order;//排序字段
    private String orderType;//排序方式 Asc/Desc
    private String dateField;//时间字段
    private String startTime;//时间范围-开始时间
    private String endTime;//时间范围-开始时间

    public String getOrderType() {
        if (StringUtils.isBlank(orderType)) {
            orderType = SortOrder.Desc.name();
        }
        return orderType;
    }

    public Integer getSize() {
        return size == 0 ? 30 : size;
    }

    public Integer getFrom() {
        return getIndex() != 0 ? ((getIndex() - 1) * getSize()) : 0;
    }

    public Integer getIndex() {
        return null == index ? 0 : index;
    }

    public String getStartTime(int offset) {
        if (StringUtils.isBlank(startTime)) {
            startTime = DateUtil.format(DateUtil.offsetDay(new Date(), offset), "yyyy-MM-dd 00:00:00");
            return String.valueOf(DateUtil.parse(startTime, "yyyy-MM-dd 00:00:00").getTime());
        }
        return startTime;
    }

    public String getEndTime() {
        if (StringUtils.isBlank(endTime)) {
            endTime = String.valueOf(System.currentTimeMillis());
        }
        return endTime;
    }
}
2.4.3.查询工具类
@Component
public class ElasticClientUtils<T> {

    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字查询
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFiled(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.term(t -> t
                                .field(dto.getField())
                                .value(dto.getWord())
                        )).sort(sorts),
                HashMap.class);
        return getResult(target, result, search);
    }

    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字查询,基于游标查询scroll
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFileds(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        getFieldValues(dto, queries);
        //使用scroll深度分页查询
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))).size(5000).scroll(t -> t.time("5s"))
                        .sort(sorts),
                HashMap.class);
        StringBuffer scrollId = new StringBuffer(search.scrollId());
        //循环查询,直到查不到数据
        do {
            getResult(target, result, search);
            StringBuffer finalScrollId = scrollId;
            search = client.scroll(s -> s.scrollId(finalScrollId.toString()).scroll(t -> t.time("5s")), HashMap.class);
            scrollId = new StringBuffer(search.scrollId());
        } while (!search.hits().hits().isEmpty());
        //getResult(target, result, search)
        return result;
    }

    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFiledWithPage(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.term(t -> t
                                .field(dto.getField())
                                .value(dto.getWord())
                        )).sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }


    private List<T> getResult(Class<T> target, List<T> result, SearchResponse<HashMap> search) {
        List<Hit<HashMap>> hits = search.hits().hits();
        Iterator<Hit<HashMap>> iterator = hits.iterator();
        while (iterator.hasNext()) {
            Hit<HashMap> decodeBeanHit = iterator.next();
            Map<String, Object> docMap = decodeBeanHit.source();
            docMap.put("id", decodeBeanHit.id());
            String json = JSON.toJSONString(docMap);
            T obj = JSON.parseObject(json, target);
            result.add(obj);
        }
        return result;
    }

    /**
     * @param
     * @param client
     * @param dto
     * @return long
     * @author liuch
     * @description 根据关键字查询总条数
     * @date 2022/4/2 17:15
     */
    public static long queryCountByFiled(ElasticsearchClient client, EsQueryDTO dto) throws Exception {
        CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.term(t -> t
                .field(dto.getField())
                .value(dto.getWord())
        )));
        long total = count.count();
        return total;
    }

    /**
     * @param
     * @param client
     * @param dto
     * @return long
     * @author liuch
     * @description 根据关键字查询总条数-复合查询
     * @date 2022/4/2 17:15
     */
    public static long queryCountByFileds(ElasticsearchClient client, List<Query> queries, EsQueryDTO dto) throws Exception {
        getFieldValues(dto, queries);
        CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))));
        long total = count.count();
        return total;
    }


    /**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  must
     * @date 2022/4/2 17:15
     */
    public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.must(queries)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }

/**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  must 过滤
     * @date 2022/4/2 17:15
     */
    public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, List<Query> filters, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.must(queries).filter(filters)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }


    /**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  should
     * @date 2022/4/2 17:15
     */
    public List<T> queryShouldByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.should(queries)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }

    /**
     * 构件复合查询条件
     *
     * @param dto
     * @param queries
     */
    private static void getFieldValues(EsQueryDTO dto, List<Query> queries) {
        List<FieldValue> fieldValues = new ArrayList<>();
        //根据关键字列表构件复合查询的值
        dto.getWords().stream().forEach(word -> fieldValues.add(FieldValue.of(word)));
        //查询条件列表
        queries.add(Query.of(q -> q.terms(t -> t.field(dto.getField()).terms(v -> v.value(fieldValues)))));
    }


    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.lang.Object
     * @author liuch
     * @description 根据文档id查询
     * @date 2022/4/2 17:16
     */
    public Object queryByDocumentId(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        GetResponse<HashMap> getResponse = client.get(s -> s
                        .index(dto.getIndexName()).id(dto.getWord()),
                HashMap.class);
        getResponse.source();
        Map<String, Object> docMap = getResponse.source();
        String json = JSON.toJSONString(docMap);
        T obj = JSON.parseObject(json, target);
        return obj;
    }

}
2.4.4.基础操作接口
/**
 * 基础操作---接口
 */
public interface IElasticSearchIRepository<T, V> {


    int delete(V id);

    int update(T entity);

    T getById(V id);
   
    List<T> getAll();

    long count();

    PageInfo<T> getListByPage(int pageIndex, int pageSize);

    /**
     * 新增一个文档
     *
     * @param entity 实体类
     * @return
     */
    IndexResponse createByFluentDSL(T entity);

    /**
     * 新增一个文档
     *
     * @param entity 实体类
     * @return
     */
    IndexResponse createByBuilderPattern(T entity);

    /**
     * 批量增加文档
     *
     * @param list 对象集合
     * @return 批量操作的结果
     */
    BulkResponse bulkCreate(List<T> list);

   /**
     * 根据文档id查找文档,返回类型是ObjectNode
     *
     * @param id  文档id
     * @return ObjectNode类型的查找结果
     */
    ObjectNode getObjectNodeById(V id);


    /**
     * 批量删除文档
     *
     * @param docIds  要删除的文档id集合
     * @return
     * @throws Exception
     */
    BulkResponse bulkDeleteByIds(List<V> docIds);

    /**
     * 根据文档id删除文档
     *
     * @param idxName 索引名
     * @param docId   文档id
     * @return Object类型的查找结果
     * @throws Exception
     */
    Boolean deleteById(String idxName, String docId) throws IOException;

    
    /**
     * 新建索引,指定索引名称
     *
     */
    Boolean createIndex();

    /**
     * 创建索引,指定索引名称和setting和mapping
     *
     * @param settingFn - 索引参数
     * @param mappingFn - 索引结构
     */
    Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                     Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn);

    /**
     * 删除索引
     * @throws IOException
     */
    Boolean deleteIndex();

    /**
     * 修改索引字段信息 <br/>
     * 字段可以新增,已有的字段只能修改字段的 search_analyzer 属性。
     *
     * @param propertyMap - 索引字段,每个字段都有自己的property
     * @throws IOException
     */
    Boolean updateIndexProperty(HashMap<String, Property> propertyMap);

    

    /**
     * 查询索引列表
     *
     * @return
     * @throws IOException
     */
    GetIndexResponse getIndexList();

    /**
     * 查询索引详情
     *
     * @return
     * @throws IOException
     */
    GetIndexResponse getIndexDetail();

    /**
     * 检查指定名称的索引是否存在
     *
     * @return - true:存在
     * @throws IOException
     */
    boolean indexExists();

}
2.4.5.基础操作接口实现类
public abstract class ElasticSearchIRepository<T,V> implements IElasticSearchIRepository<T,V> {

    @Autowired(required =false)
    @Qualifier("elasticsearchClient")
    private ElasticsearchClient elasticsearchClient;

    protected ElasticSearchDocument getEntityProperties() {
        Class<T> cls = getEntityClass();
        ElasticSearchDocument esDoc = cls.getAnnotation(ElasticSearchDocument .calss);
        return esDoc;
    }

    /**设置索引全局配置*/
    protected abstract Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings();

    /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
    protected abstract Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings();

    protected abstract Class<T> getEntityClass();


    @Override
    public int update(T entity) {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            UpdateRequest updateRequest = new UpdateRequest.Builder()
                    .index(doc.index())
                    .id(entity.getId().toString())
                    .doc(entity)
                    .build();
            UpdateResponse updateResponse = elasticsearchClient.update(updateRequest, entity.getClass());
            return updateResponse != null && StringUtils.isNotEmpty(updateResponse.id()) ? 1 : 0;
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }

   @Override
    public PageInfo<T> getListByPage(int pageIndex, int pageSize) {
         List<T> list = new ArrayList<>();
         try {
            ElasticSearchDocument doc = getEntityProperties();
            ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndex(paeIndex);
            dto.setSize(pageSize);
            dto.setIndexName(doc.index());
            list = elasticClientUtils.queryPage(elasticsearchClient, dto, getEntityClass());
            return new PageInde<T>(pageIndex, pageSize, (long)list.size(), list);
         }
         catch (IOException e) {
            log.error(e);
         }
         return new PageInde<T>(pageIndex, pageSize, 0L, list);
    }

   @Override
    public int delete(V id) {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            DeleteResponse delete = elasticsearchClient.delete(d -> d
                    .index(doc.index())
                    .id(id.toString()));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值