Elasticsearch8搭建及Springboot中集成使用

1.搭建

1.1.下载地址

Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch
Kibana:https://www.elastic.co/cn/downloads/kibana

1.2.具体过程

下载安装包:访问上述链接,下载适合你操作系统的Elasticsearch和Kibana安装包。

1.3.安装Elasticsearch

解压下载的安装包。
进入解压后的目录。
如果是Windows系统,直接进入bin目录,双击elasticsearch.bat文件。看到命令行中打印日志中出现“started”,说明Elasticsearch启动完成。

linux中进入bin目录,然后执行./elasticsearch命令

详情参见linux系统安装elasticsearch教程_linux安装es-CSDN博客

1.4.配置Elasticsearch集群

修改elasticsearch.yml文件,设置集群名称、节点名称、网络主机和种子节点等。
对于集群中的其他节点,重复上述步骤,并确保每个节点的配置文件中都有所有节点的IP地址。

启动其他节点:在每个节点上重复上述安装步骤,并启动Elasticsearch服务。

检查集群健康状态:通过访问Elasticsearch的API或使用Kibana界面,查看集群的健康状态。

请注意,这只是一个基本的搭建指南。在生产环境中,你可能需要更详细的配置和优化。此外,确保你的网络设置允许Elasticsearch集群通信所需的端口。

1.5.注意点

1.不能用root权限启动,需要新建用户,如:

更改文件夹的用户为user1  chown -R user1:user1 /local
修改user1对文件夹的权限  chmod 777 /local

2.获取账号密码

elasticsearch的bin目录下,输入命令行:elasticsearch-reset-password -u elastic

2.springboot中集成ES8

2.1.依赖

<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.1.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>
<dependency>
    <groupId>jakarta.json</groupId>
    <artifactId>jakarta.json-api</artifactId>
    <version>2.0.1</version>
</dependency>

2.2.elasticsearch.properties

spring.elasticsearch.uris = IP:port
spring.elasticsearch.username = 用户名
spring.elasticsearch.password = 密码

2.3.ElasticSearchConfig

@Configuration
public class ElasticSearchConfig {

    @Value("${spring.elasticsearch.uris}")
    private String hosts;

    @Value("${spring.elasticsearch.username}")
    private String userName;

    @Value("${spring.elasticsearch.password}")
    private String passWord;

    @Bean(name="elasticsearchClient")
    public ElasticsearchClient elasticsearchClient(){
        HttpHost[] httpHosts = toHttpHost();
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                AuthScope.ANY, new UsernamePasswordCredentials(userName, passWord));

        RestClientBuilder builder = RestClient.builder(httpHosts);
        builder.setRequestConfigCallback(
                new RestClientBuilder.RequestConfigCallback() {
                    @Override
                    public RequestConfig.Builder customizeRequestConfig(
                            RequestConfig.Builder requestConfigBuilder) {
                        return requestConfigBuilder.setSocketTimeout(60000).setConnectTimeout(5000);
                    }
                });
        builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {

                return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            }
        });
        RestClient restClient = builder.build();
        ElasticsearchTransport transport = new RestClientTransport(restClient,new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }

    private HttpHost[] toHttpHost() {
        if (!StringUtils.hasLength(hosts)) {
            throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
        }
        // 多个IP逗号隔开
        String[] hostArray = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }
        return httpHosts;
    }
}

2.4.通用类

2.4.1.枚举类,ES实体类注解

@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()));
            return delete.forcedRefresh() ? 1 : 0;
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }

    @Override
    public List<T> getAll() {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndexName(doc.index());
            return elasticClientUtils.queryAll(elasticsearchClient, dto, getEntityClass());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public long count() {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndexName(doc.index());
            return ElasticClientUtils.queryCountByFiled(elasticsearchClient, dto);
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }

    @Override
    public IndexResponse createByFluentDSL(T entity) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            IndexResponse response = elasticsearchClient.index(index -> idx
                     .index(doc.index())
                     .id(entity.getId().toString())
                     .document(entity));
            return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public IndexResponse createByBuilderPattern(T entity) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            IndexRequest.Builder<Object> indexReqBuilder = new IndexRequest.Builder<>();

            indexReqBuilder.index(doc.index());
            indexReqBuilder.id(entity.getId().toString());
            indexReqBuilder.document(entity);
            return elasticsearchClient.index(indexReqBuilder.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public BulkResponse bulkCreate(List<T> documents) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            BulkRequest.Builder br = new BulkRequest.Builder();
            documents.stream()
                .forEach(esDocument -> br
                        .operations(op -> op
                                .index(idx -> idx
                                        .index(doc.index())
                                        .id(esDocument.getId().toString())
                                        .document(esDocument))));

            return elasticsearchClient.bulk(br.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public T getById(V id) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetResponse<Object> response = elasticsearchClient.get(g -> g
                        .index(doc.index())
                        .id(id.toString()),
                Object.class);
        return response.found() ? FastJsonUtil.fromJson(response.source().toString(), getEntityClass()) : null;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public ObjectNode getObjectNodeById(V id) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetResponse<ObjectNode> response = elasticsearchClient.get(g -> g
                        .index(doc.index())
                        .id(id.toString()),
                ObjectNode.class);

        return response.found() ? response.source() : null;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

   

    @Override
    public BulkResponse bulkDeleteByIds(List<V> docIds) {

        try {
            ElasticSearchDocument doc = getEntityProperties();
            BulkRequest.Builder br = new BulkRequest.Builder();

             // 将每一个对象都放入builder中
             docIds.stream().forEach(id -> br
                .operations(op -> op
                        .delete(d -> d
                                .index(doc.index())
                                .id(id.toString()))));

             return elasticsearchClient.bulk(br.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

   /**自动创建映射*/
    @Override
    public Boolean createIndex() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            CreateIndexResponse response = elasticsearchClient.indices().create(c -> c.index(doc.index()));
        log.info("createIndex方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
    }

    /**手动创建映射*/
    @Override
    public Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                            Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) {

        try {
            ElasticSearchDocument doc = getEntityProperties();
            CreateIndexResponse response = elasticsearchClient
                .indices()
                .create(c -> c
                        .index(doc.index())
                        .settings(settingFn)
                        .mappings(mappingFn)
                );
        log.info("createIndex方法,acknowledged={}", response.acknowledged());
          return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
        
    }

    @Override
    public Boolean deleteIndex() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            DeleteIndexResponse response = elasticsearchClient.indices().delete(c -> c.index(doc.index()));
        log.info("deleteIndex方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
        
    }

    @Override
    public Boolean updateIndexProperty(HashMap<String, Property> propertyMap) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            PutMappingResponse response = elasticsearchClient.indices()
                .putMapping(typeMappingBuilder ->
                        typeMappingBuilder
                                .index(doc.index())
                                .properties(propertyMap)
                );
        log.info("updateIndexMapping方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
    }

    @Override
    public GetIndexResponse getIndexList() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            //使用 * 或者 _all都可以
        GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index("_all"));
        log.info("getIndexList方法,response.result()={}", response.result().toString());
        return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }

    @Override
    public GetIndexResponse getIndexDetail() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index(doc.index()));
        log.info("getIndexDetail方法,response.result()={}", response.result().toString());
        return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
        
    }

    @Override
    public boolean indexExists() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            return elasticsearchClient.indices().exists(b -> b.index(doc.index())).value();
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }  

}

2.5.业务

2.5.1.接口

pulbic interface testRepo extends IElasticSearchIRepository<TestESDO, Long> {

}

2.5.2. 实现类

@component
pulbic calss testRepo extends ElasticSearchIRepository<TestESDO, Long> implements testRepo{
    /**设置索引全局配置*/
    @Override
    protected Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings() {
        return builder -> builder.numberOfShards("3").numberOfReplicas("1");
     }

    /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
    @Override
    protected Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings() {
    return builder -> {
        HashMap<String, Property> propertiesMap = new HashMap<>();
        propertiesMap.put("id", new Property.Builder().Long_(new LongNumberProperty.Builder().build()).build());
        return builder.properties(propertiesMap);
    }
 }

    @Override
    protected Class<T> getEntityClass() {
    return TestESDO.clas;    
}
}

2.5.3. 实体类

@Data
@ElasticSearchCocument(index="test")
public class TestESDO {
 
   private Long id;
}

2.5.4. 常见查询方法

1.使用MultiMatch可以多字段,如果想要把搜索词当成一个整体来匹配查询还需要增加TextQueryType.Phrase,如

//must复合查询
List<Query> queries = new ArrayLict<>();
MultiMatchQuery multiMatchQuery = new MultiMatchQuery.Builder()
        .query("搜索词")
         .type(TextQueryType.Phrase)
         .fields("字段1", "字段2")
         .build();
Query query = new Query.Builder()
         .multiMatch(multiMatchQuery).build();
queries.add(multiMatchQuery);

2.使用TermsQuery进行数组过滤,如对某个字段[1,2,3,4]进行过滤,要求只有搜索词中包含这些数字就进行匹配,如4,5或者1,2,3或者1,代码如下

//过滤
List<Query> filters = new ArrayLict<>();
List<FieldValue> fieldValueList = new ArrayList<>();
fieldValueList.add(new FieldValue.Builder().longValue(1).buld());
TermsQuery termsQuery = new TermsQuery .Builder()
         .field("字段1")
         .terms(new TermsQueryField.Builder().value(fieldValueList).build())
         .build();
Query filter = new Query.Builder()
         .terms(termsQuery).build();
filters.add(filter);

3.更多查询参见:ElasticSearch使用教程、设计到实战-CSDN博客 

相关推荐

  1. Elasticsearch8Springboot集成使用

    2024-03-21 10:58:01       18 阅读
  2. ElasticSeach--springboot使用

    2024-03-21 10:58:01       38 阅读
  3. SpringBoot集成Elasticsearch实例

    2024-03-21 10:58:01       9 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-21 10:58:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-21 10:58:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-21 10:58:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-21 10:58:01       20 阅读

热门阅读

  1. ffmpeg不常用命令整理

    2024-03-21 10:58:01       19 阅读
  2. docker基础(三)之docker rm和docker rmi

    2024-03-21 10:58:01       19 阅读
  3. 蓝队面试场景题,面试经验小记

    2024-03-21 10:58:01       17 阅读
  4. ubuntu18.04安装ffmpeg

    2024-03-21 10:58:01       15 阅读
  5. Onedrive技巧与问题

    2024-03-21 10:58:01       17 阅读
  6. vty实验

    vty实验

    2024-03-21 10:58:01      17 阅读