Spring Boot中用RestHighLevelClient按条件查询Elasticsearch索引数据的实现
Spring Boot 基于 RestHighLevelClient 的 Elasticsearch 条件查询实现
前置检查
- 确认索引
es_52_companydetails_index中companyaddress字段映射为nested类型,否则嵌套数组查询无法精准过滤单个子元素,会默认返回数组全部内容,无法满足第二个查询场景的要求
场景1:按company_name查询,返回该公司所有company_name/address3组合
@Autowired private RestHighLevelClient restHighLevelClient; public List<String> queryByCompanyName(String companyName) throws IOException { SearchRequest searchRequest = new SearchRequest("es_52_companydetails_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 精准匹配company_name,字段为text类型需加.keyword后缀,keyword类型可直接写字段名 sourceBuilder.query(QueryBuilders.termQuery("company_name.keyword", companyName)); // 仅返回业务需要的字段,减少IO消耗 sourceBuilder.fetchSource(new String[]{"company_name", "companyaddress.address3"}, null); searchRequest.source(sourceBuilder); SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); List<String> result = new ArrayList<>(); for (SearchHit hit : response.getHits().getHits()) { Map<String, Object> sourceMap = hit.getSourceAsMap(); String name = (String) sourceMap.get("company_name"); List<Map<String, Object>> addressList = (List<Map<String, Object>>) sourceMap.get("companyaddress"); for (Map<String, Object> address : addressList) { result.add(name + "/" + address.get("address3")); } } return result; }
场景2:按address3查询,仅返回匹配的company_name/address3组合
public List<String> queryByAddress3(String address3) throws IOException { SearchRequest searchRequest = new SearchRequest("es_52_companydetails_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 构建nested嵌套查询 NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("companyaddress", QueryBuilders.termQuery("companyaddress.address3.keyword", address3), ScoreMode.None); sourceBuilder.query(nestedQuery); // 主查询仅返回公司名称,匹配的地址从inner_hits中获取 sourceBuilder.fetchSource(new String[]{"company_name"}, null); // 开启inner_hits只返回命中的嵌套子对象,而非整个数组 nestedQuery.innerHit(new InnerHitBuilder("matched_address")); searchRequest.source(sourceBuilder); SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); List<String> result = new ArrayList<>(); for (SearchHit hit : response.getHits().getHits()) { String name = (String) hit.getSourceAsMap().get("company_name"); // 从inner_hits中提取匹配的address3 SearchHits innerHits = hit.getInnerHits().get("matched_address"); for (SearchHit innerHit : innerHits.getHits()) { String matchedAddr = (String) innerHit.getSourceAsMap().get("address3"); result.add(name + "/" + matchedAddr); } } return result; }
补充说明
- 上述代码默认字段为text+keyword双类型,若你的索引中字段本身就是keyword类型,去掉查询条件中的
.keyword后缀即可 - IOException的捕获和处理逻辑可根据项目自身的异常规范调整
内容的提问来源于stack exchange,提问作者Dorayya
相关产品推荐
相关产品推荐

