Springboot项目如何使用Elasticsearch

Springboot项目如何使用Elasticsearch


用的是阿里云elasticsearch集群,所以需要初始化连接代码。

  1. 导入Maven依赖
		<dependency>
			<groupId>co.elastic.clients</groupId>
			<artifactId>elasticsearch-java</artifactId>
			<version>8.9.1</version>
		</dependency>

		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-client</artifactId>
			<version>7.17.16</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.12.3</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.12.3</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.12.3</version>
		</dependency>
  1. 编写elasticsearch方法工具类
@Slf4j
@Component
public class ElasticSearchServiceImpl implements IElasticSearchService {

    /**
     *
     */
    private ElasticsearchClient elasticsearchClient;

    /**
     * 初始化方法
     */
    @PostConstruct
    private void init(){
        log.info("初始化es链接信息");
        // 阿里云Elasticsearch集群需要basic auth验证。
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

        String userName = "***";
        String password = "******";
        String url = "***.public.elasticsearch.aliyuncs.com";
        final int maxConnTotal = 200;
        final int maxConnPerRoute = 50;

        //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
        // 通过builder创建rest client,配置http client的HttpClientConfigCallback。
        // 单击所创建的Elasticsearch实例ID,在基本信息页面获取公网地址,即为ES集群地址。
        RestClient restClient = RestClient.builder(new HttpHost(url, 9200, "http"))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        httpClientBuilder.setMaxConnTotal(maxConnTotal);
                        httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                }).build();

        // 使用 Jackson 映射器创建传输
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

        // 创建 API 客户端
        this.elasticsearchClient = new ElasticsearchClient(transport);
        log.info("初始化es链接信息完毕");
    }

    @Override
    public <T> void indexDocments(String indexName, String id, T document) {
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isBlank(id,"es索引名称id不能为空");
        Assert.isNull(document,"es索引名称实体内容不能为空");
        try {
            elasticsearchClient.index(i -> i
                    .index(indexName)
                    .id(id)
                    .document(document)
            );
        } catch (IOException e) {
            log.error("elastic search indexDocments error:",e);
        }
    }

    @Override
    public <T> List<Boolean> bulkIndexDocuments(String indexName, List<String> idList, List<T> documents) {
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isTrue(CollUtil.isEmpty(idList),"es索引名称id列表不能为空");
        Assert.isNull(CollUtil.isEmpty(documents),"es索引名称实体内容列表不能为空");
        BulkRequest.Builder br = new BulkRequest.Builder();
        List<Boolean> resultList = new ArrayList<>();

        for (int i=0;i<documents.size();i++) {
            int finalI = i;
            br.operations(op -> op
                    .index(idx -> idx
                            .index(indexName)
                            .id(idList.get(finalI))
                            .document(documents.get(finalI))
                    )
            );
        }

        try {
            BulkResponse result = elasticsearchClient.bulk(br.build());

            for (BulkResponseItem item: result.items()) {
                if (item.error() != null) {
                    resultList.add(false);
                    log.error("批量插入es文档单个错误:"+item.error().reason());
                }else{
                    resultList.add(true);
                }
            }
        } catch (IOException e) {
            log.error("批量插入es文档失败:",e);
        }
        return resultList;
    }

    @Override
    public <T> T searchDocumentsById(String indexName, String id, Class<T> clz) {
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isBlank(id,"es索引名称id不能为空");
        Assert.isNull(clz,"es索引名称实体类型不能为空");
        T document = null;
        try {
            GetResponse<T> response = elasticsearchClient.get(g -> g
                            .index(indexName)
                            .id(id), clz
            );
            if (response.found()) {
                document = response.source();
            }
        } catch (IOException e) {
	        log.error("根据id[{}]查询es文档失败:", id, e);
        }
        return document;
    }

    @Override
    public <T> ElasticSearchPageResult<T> pageDocumentsWithSingleFiled(String indexName, String fieldName, String fieldValue, Integer page, Integer size, Class<T> clz) {
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isBlank(fieldName,"es查询字段名称不能为空");
        Assert.isBlank(fieldValue,"es查询字段内容不能为空");
        Assert.isNull(page,"es分页查询页码不能为空");
        Assert.isNull(size,"es分页查询页大小不能为空");
        Assert.isNull(clz,"es索引名称实体类型不能为空");
        ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
        try {
            SearchResponse<T> response = elasticsearchClient.search(s -> s
                            .index(indexName)
                            .query(q -> q
                                    .match(t -> t
                                            .field(fieldName)
                                            .query(fieldValue)
                                    )
                            ).from((page-1)*size).size(size),
                    clz
            );

            TotalHits total = response.hits().total();
            if(total.value() > 0){
                List<T> documentList = new ArrayList<>();
                elasticSearchPageResult.setTotalHits(total.value());
                List<Hit<T>> hits = response.hits().hits();
                for (Hit<T> hit: hits) {
                    documentList.add(hit.source());
                }
                elasticSearchPageResult.setRecords(documentList);
            }

        } catch (IOException e) {
            log.error("查询es文档失败",e);
        }
        return elasticSearchPageResult;
    }

    @Override
    public <T> ElasticSearchPageResult<T> pageDocuments(String indexName, Integer page, Integer size, Class<T> clz) {
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isNull(page,"es分页查询页码不能为空");
        Assert.isNull(size,"es分页查询页大小不能为空");
        Assert.isNull(clz,"es索引名称实体类型不能为空");
        ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
        try {
            SearchResponse<T> response = elasticsearchClient.search(s -> s
                            .index(indexName)
                            .query(q -> q
                                    .matchAll(t -> t)
                            )
                            .sort(so -> so
                                    .field(f -> f
                                            .field("id")
                                            .order(SortOrder.Desc)
                                    )
                            )
                            .from((page-1)*size).size(size),
                    clz
            );

            TotalHits total = response.hits().total();
            if(total.value() > 0){
                List<T> documentList = new ArrayList<>();
                elasticSearchPageResult.setTotalHits(total.value());
                List<Hit<T>> hits = response.hits().hits();
                for (Hit<T> hit: hits) {
                    documentList.add(hit.source());
                }
                elasticSearchPageResult.setRecords(documentList);
            }

        } catch (IOException e) {
            log.error("查询es文档失败",e);
        }
        return elasticSearchPageResult;
    }

    @Override
    public List<Boolean> bulkDeleteDocuments(String indexName, List<String> idList){
        Assert.isBlank(indexName,"es索引名称不能为空");
        Assert.isTrue(CollUtil.isEmpty(idList),"es索引名称id列表不能为空");
        BulkRequest.Builder br = new BulkRequest.Builder();
        List<Boolean> resultList = new ArrayList<>();

        for (String id : idList) {
            br.operations(op -> op
                    .delete(del -> del
                            .index(indexName)
                            .id(id)
                    )
            );
        }

        try {
            BulkResponse result = elasticsearchClient.bulk(br.build());
            for (BulkResponseItem item : result.items()) {
                if (item.error() != null) {
                    resultList.add(false);
                    log.error("批量删除es文档单个错误:{}", item.error().reason());
                } else {
                    resultList.add(true);
                }
            }
        } catch (IOException e) {
            log.error("批量删除es文档失败:", e);
        }
        return resultList;
    }

    @Override
    public <T> ElasticSearchPageResult<T> pageDocumentContainEqFieldList(String indexName, String fieldName, String fieldValue, Integer page, Integer size, Class<T> clz) {
        Assert.isBlank(indexName, "es索引名称不能为空");
        Assert.isBlank(fieldName, "es查询字段名称不能为空");
        Assert.isBlank(fieldValue, "es查询字段内容不能为空");
        Assert.isNull(page, "es分页查询页码不能为空");
        Assert.isNull(size, "es分页查询页大小不能为空");
        Assert.isNull(clz, "es索引名称实体类型不能为空");
        ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
        try {
            SearchResponse<T> response = elasticsearchClient.search(s -> s
                            .index(indexName)
                            .query(q -> q
                                    .queryString(qs -> qs
                                            .defaultField(fieldName)
                                            // 使用es的短语搜索 精确匹配
                                            .query("\"" + fieldValue + "\"")
                                    )
                            ).from((page - 1) * size).size(size),
                    clz
            );

            TotalHits total = response.hits().total();
            if (total.value() > 0) {
                List<T> documentList = new ArrayList<>();
                elasticSearchPageResult.setTotalHits(total.value());
                List<Hit<T>> hits = response.hits().hits();
                for (Hit<T> hit : hits) {
                    documentList.add(hit.source());
                }
                elasticSearchPageResult.setRecords(documentList);
            }
        } catch (IOException e) {
            log.error("查询es文档失败", e);
        }
        return elasticSearchPageResult;
    }

    @Override
    public <T> ElasticSearchPageResult<T> pageCustomizeDocumentList(EsPageCustomizeQueryDTO esQuery, Function<Query.Builder, ObjectBuilder<Query>> queryCondition, Class<T> clz) {
        Assert.isBlank(esQuery.getIndexName(), "es索引名称不能为空");
        Assert.isNull(queryCondition, "es查询条件不能为空");
        Assert.isNull(esQuery.getFrom(), "es分页查询页码不能为空");
        Assert.isNull(esQuery.getSize(), "es分页查询页大小不能为空");
        Assert.isNull(clz, "es索引名称实体类型不能为空");
        ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
        try {
            SearchResponse<T> response = elasticsearchClient.search(s -> s
                            .index(esQuery.getIndexName())
                            .query(queryCondition)
                            .from((esQuery.getFrom() - 1) * esQuery.getSize())
                            .size(esQuery.getSize()),
                    clz
            );
            TotalHits total = response.hits().total();
            if (total.value() > 0) {
                List<T> documentList = new ArrayList<>();
                elasticSearchPageResult.setTotalHits(total.value());
                List<Hit<T>> hits = response.hits().hits();
                for (Hit<T> hit : hits) {
                    documentList.add(hit.source());
                }
                elasticSearchPageResult.setRecords(documentList);
            }
        } catch (IOException e) {
            log.error("查询es文档失败", e);
        }
        return elasticSearchPageResult;
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot项目使用Elasticsearch,需要在pom.xml文件中添加相关依赖。以下是一个使用Spring BootElasticsearch的简单示例: 1.添加依赖 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2.配置Elasticsearch属性 在application.properties文件中添加Elasticsearch的配置属性,例如: ```properties spring.data.elasticsearch.cluster-name=my-application spring.data.elasticsearch.cluster-nodes=localhost:9300 ``` 3.定义实体类 在Spring Boot应用程序中,可以使用Spring Data Elasticsearch来定义Elasticsearch实体类。例如: ```java @Document(indexName="blog",type="article") public class Article { @Id private String id; private String title; private String content; // getters and setters } ``` 4.定义Elasticsearch存储库 定义一个Elasticsearch存储库接口,例如: ```java public interface ArticleRepository extends ElasticsearchRepository<Article, String> { List<Article> findByTitle(String title); } ``` 5.在服务中使用Elasticsearch存储库 在服务中注入Elasticsearch存储库,并使用它执行Elasticsearch操作,例如: ```java @Service public class ArticleService { @Autowired private ArticleRepository articleRepository; public List<Article> search(String title) { return articleRepository.findByTitle(title); } public void save(Article article) { articleRepository.save(article); } } ``` 这是一个简单的示例,演示了如何在Spring Boot应用程序中使用Elasticsearch。你可以使用这个示例作为起点,根据自己的需求进行修改和扩展。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值