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

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

前言:在之前讲过通过排序在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.csdn.net/m0_37914467/article/details/108519693

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值