目的:通过经纬度查询获取距离
前言:在之前讲过通过排序在es的sort域中可以获取距离返回值,这次说一下如果不排序怎么获取距离的返回值
实现方式:采用es脚本实现
1.dsl语言实现:可在kibana插件查询
GET process/_doc/_search
{
"_source":[],
"script_fields": {
"distance": {
"script": {
"source": "doc['location'].arcDistance(params.lat,params.lon)",
"lang": "painless",
"params": {
"lat": 40,
"lon": 120
}
}
}
}
}
如果文档中没有经纬度字段,则会报错,可以加判断
GET process/_doc/_search
{
"query": {
"bool": {
"must": [
{
"terms": {
"taskId": [
"776859821306544129",
"776859900981542913"
],
"boost": 1.0
}
},
{
"script": {
"script": {
"lang": "painless",
"source": "doc['formObject.location'].size()>0"
}
}
}
]
}
},
"_source":[],
"script_fields": {
"distance": {
"script": {
"source": "doc['formObject.location'].arcDistance(params.lat,params.lon)",
"lang": "painless",
"params": {
"lat": 40,
"lon": 120
}
}
}
}
}
查询结果:默认是以m为单位,如需转换成km,记得处理一下就行
说明:上述语句中location为距离的字段名称,params是经纬度参数,在java代码中可动态传递;“script_fields”中的设置可以计算出距离并返回,但是由于设置了fields字段,所以不会有原始文档返回值,所以要加上"_source":[]
2.java代码实现
Map<String, Object> params = new HashMap<String, Object>();//距离脚本参数
//参数赋值
params.put("lat", 纬度);
params.put("lon", 经度);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
if(!params.isEmpty()){//params为经纬度参数
Script script = new Script(ScriptType.INLINE, "painless",
"doc['formObject.location'].arcDistance(params.lat,params.lon)", params);
searchSourceBuilder.scriptField("distance", script);
searchSourceBuilder.fetchSource("*", null);//设置返回所有字段,不设置的话只会返回fields
}
searchSourceBuilder.timeout(new TimeValue(120,TimeUnit.SECONDS));
SearchRequest searchRequest = new SearchRequest("process");
searchRequest.source(searchSourceBuilder);
SearchResponse response = esService.getClient().search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
for(SearchHit hit : hits){
JSONObject jsonObject = JSONObject.parseObject(hit.getSourceAsString());
Map<String, DocumentField> fields = hit.getFields();
DocumentField documentField = fields.get("distance");
double distance = (double)documentField.getValues().get(0);//距离值
}
注:因只说明如果用脚本实现添加距离返回值,所以部分基础代码没有贴出,如需要,请参考上一篇文章
https://blog.youkuaiyun.com/m0_37914467/article/details/108519693