Spring Boot结合Spring Data Elasticsearch如何返回距离与全部字段
Spring Data Elasticsearch 实现带script_fields的ES查询方案
完整实现代码
import org.springframework.data.elasticsearch.core.query.ScriptField; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.FetchSourceFilter; import org.springframework.data.domain.PageRequest; import org.elasticsearch.index.query.BoolQueryBuilder; import static org.elasticsearch.index.query.QueryBuilders.*; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.script.Script; // 1. 构造原生查询对应的Bool查询条件 BoolQueryBuilder boolQueryBuilder = boolQuery() .should(constantScoreQuery(termQuery("my_field", "my_value")).boost(10)) .should(constantScoreQuery(termQuery("my_field", "my_value")).boost(8)) .filter(termsQuery("my_array_field", "first_value", "second_value")) .filter(geoDistanceQuery("location") .distance("10km") .lat(40) .lon(2) ); // 2. 构造距离计算的脚本字段 Script distanceScript = new Script("doc['location'].arcDistance(40, 2) / 1000"); ScriptField distanceScriptField = new ScriptField("distance", distanceScript); // 3. 构造完整查询对象 NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder() .withQuery(boolQueryBuilder) .withPageable(PageRequest.of(page, size)) // 注入脚本字段 .withScriptField(distanceScriptField) // 显式配置返回全部_source字段 .withSourceFilter(new FetchSourceFilter(true, null)) // 按得分降序排序 .withSort(SortBuilders.scoreSort().order(SortOrder.DESC)) .build(); // 4. 执行查询并获取返回的距离值 SearchHits<MyIndexedDocument> searchHits = elasticsearchOperations.search(nativeSearchQuery, MyIndexedDocument.class); // 遍历结果获取每条记录的距离 for (SearchHit<MyIndexedDocument> hit : searchHits) { Double distance = (Double) hit.getFields().get("distance").getValue(); // 后续可将距离赋值给实体类或做业务处理 }
疑问解答
1. ScriptField的正确使用方式
- 先构造
org.elasticsearch.script.Script对象,传入你需要执行的Painless脚本内容 - 再构造
org.springframework.data.elasticsearch.core.query.ScriptField对象,第一个参数为返回的脚本字段名,第二个参数为上述构造的Script对象 - 调用
NativeSearchQueryBuilder的withScriptField方法传入构造好的ScriptField即可 - 查询执行完成后,从
SearchHit的getFields()方法中即可取到对应名称的脚本字段值
2. 配置返回全部_source字段的方法
可以直接通过NativeSearchQuery完成配置,只需要在构造查询时调用withSourceFilter方法,传入new FetchSourceFilter(true, null)即可:
- 第一个参数
true表示返回_source字段 - 第二个参数传
null表示不做字段过滤,返回全部_source字段
如果后续需要指定返回部分字段,修改第二个参数为需要保留的字段名数组即可。
内容的提问来源于stack exchange,提问作者Maaz
相关产品推荐
相关产品推荐

