使用DeleteByQueryAction删除ES指定ID文档遇类找不到错误
Elasticsearch删除指定ID文档时
ElasticsearchTransport找不到的解决办法 问题场景
尝试删除Elasticsearch中特定ID的文档,编写了如下Java代码:
// Create the low-level client RestClient restClient = RestClient.builder( new HttpHost(hostName, portName)).build(); // Create the transport with a Jackson mapper ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); // And create the API client ElasticsearchClient client = new ElasticsearchClient(transport); public long delete( String indexName, String key, String value ) { BulkByScrollResponse response = DeleteByQueryAction.INSTANCE.newRequestBuilder( client ) .filter( QueryBuilders.matchQuery( key, value ) ) .source( indexName ) .refresh( true ) .get(); logger.info( "Deleted " + response.getDeleted() + " element(s)!" ); return response.getDeleted(); }
同时在pom.xml中引入了以下依赖:
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>7.17.9</version> </dependency>
运行时出现编译错误:
error: cannot find symbol
[ERROR] symbol: class ElasticsearchTransport
问题原因
ElasticsearchTransport和ElasticsearchClient属于Elasticsearch 7.x版本推出的新REST客户端(elasticsearch-java),而你引入的transport依赖是旧版TCP传输客户端的包,两者不兼容,导致找不到对应的类。
解决步骤
- 替换pom依赖
移除旧的transport依赖,添加新客户端的必要依赖:
<!-- Elasticsearch Java REST客户端核心包 --> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>7.17.9</version> </dependency> <!-- 低级REST客户端依赖 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.17.9</version> </dependency>
- 修正代码实现
旧代码中DeleteByQueryAction是旧版High Level Client的写法,和新客户端不兼容。如果是删除单个特定ID的文档,推荐使用更高效的单文档删除API:
import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.DeleteResponse; import co.elastic.clients.elasticsearch.core.Refresh; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import com.fasterxml.jackson.databind.ObjectMapper; import co.elastic.clients.json.jackson.JacksonJsonpMapper; // 创建低级客户端 RestClient restClient = RestClient.builder(new HttpHost(hostName, portName)).build(); // 创建传输层,绑定Jackson映射器 ElasticsearchTransport transport = new RestClientTransport( restClient, new JacksonJsonpMapper(new ObjectMapper()) ); // 创建API客户端 ElasticsearchClient client = new ElasticsearchClient(transport); public long deleteById(String indexName, String docId) throws IOException { DeleteResponse response = client.delete(d -> d .index(indexName) .id(docId) .refresh(Refresh.True) ); // 判断是否删除成功 long deletedCount = response.result() == co.elastic.clients.elasticsearch.core.Result.Deleted ? 1 : 0; logger.info("Deleted " + deletedCount + " element(s)!"); return deletedCount; }
如果需要通过**匹配字段(比如按ID字段批量删除)**使用DeleteByQuery,新客户端的写法如下:
public long deleteByQuery(String indexName, String key, String value) throws IOException { DeleteByQueryResponse response = client.deleteByQuery(d -> d .index(indexName) .query(q -> q .match(m -> m .field(key) .query(value) ) ) .refresh(Refresh.True) ); logger.info("Deleted " + response.deleted() + " element(s)!"); return response.deleted(); }
内容的提问来源于stack exchange,提问作者Vio
相关产品推荐
相关产品推荐

