java结合elaticsearch实现添加距离返回字段(按经纬度)

本文介绍如何在Elasticsearch中使用Painless脚本,不依赖排序直接计算文档中'location'字段的经纬度与给定坐标之间的距离,适用于Java代码实现,并提供Java示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:通过经纬度查询获取距离

前言:在之前讲过通过排序在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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值