Java RestHighLevelClient调用DeleteByQuery无法删除索引文档问题
Elasticsearch 7.10 Delete By Query 返回删除数为0的修复方案
按以下优先级逐一排查即可解决问题:
- 检查测试文档是否实际写入索引
你贴出的代码仅构造了存储文档内容的testDoc集合,没有执行任何文档写入(Index)请求,索引内本身不存在对应数据,删除接口自然返回0。需要先补全文档写入逻辑,再执行删除操作:// 补全文档写入逻辑 IndexRequest indexRequest = new IndexRequest(indexName); indexRequest.source(testDoc); // 写入后立即刷新,确保文档可被搜索 indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); client.index(indexRequest, RequestOptions.DEFAULT); - 检查字段映射与查询方式是否匹配
如果确认文档已经写入,问题大概率出在TermQueryBuilder的使用上:如果创建索引时没有手动指定gender字段的映射,ES默认会将字符串类型字段映射为text(分词)+keyword(不分词)的双类型。TermQuery是精确匹配查询,不会对查询词做分词,直接查询gender(text类型)字段时,会因为字段写入时已经被分词处理,导致匹配不到值。
两种修复方案选其一即可:- 查询时改用不分词的
keyword子字段:request.setQuery(new TermQueryBuilder("gender.keyword", "male")); - 提前创建索引映射,将
gender字段指定为keyword类型,不需要分词:CreateIndexRequest createIndexReq = new CreateIndexRequest(indexName); createIndexReq.mapping("{\n" + " \"properties\": {\n" + " \"gender\": {\"type\": \"keyword\"}\n" + " }\n" + "}", XContentType.JSON); client.indices().create(createIndexReq, RequestOptions.DEFAULT);
- 查询时改用不分词的
- 排除近实时搜索延迟影响
ES默认的写入刷新间隔是1秒,刚写入的文档不会立刻进入可搜索状态,如果写入后马上执行删除,可能出现匹配不到数据的情况。除了在写入时设置立即刷新策略,你已经在删除请求中配置了setRefresh(true),该配置会在删除执行完成后刷新索引,不会影响删除执行阶段的文档匹配,只需要确保删除执行前文档已经完成刷新即可。 - 前置校验方式
执行删除前先调用搜索接口统计匹配条件的文档总数,确认存在符合条件的数据再执行删除,避免空跑:SearchRequest countReq = new SearchRequest(indexName); countReq.source().query(new TermQueryBuilder("gender.keyword", "male")).size(0); SearchResponse countResp = client.search(countReq, RequestOptions.DEFAULT); System.out.println("匹配的文档总数:" + countResp.getHits().getTotalHits().value);
内容的提问来源于stack exchange,提问作者Tarun Pande
相关产品推荐
相关产品推荐

