ElasticSearch2.1 基于空间位置geo_query距离计算
首先声明 我使用的ES版本是2.1,不同版本api可能不尽相同
1、首先创建索引mapping
(1)方法1
- // 创建索引方法1
- public static void createIndex2(String indexName, String indexType) throws IOException {
- Settings settings = Settings.settingsBuilder()
- .put("cluster.name", "cluster_wubing")
- .build();
- InetAddress inetAddress = InetAddress.getByName("192.168.1.107");;
- Client esClient = TransportClient.builder().settings(settings).build()
- .addTransportAddress(new InetSocketTransportAddress(inetAddress, 9300));
- //创建mapping,我这里使用的分词器analyzer/search_analyzer为ik,注意位置location类型为geo_point
- String mapping = "{\"properties\": {\n" +
- " \"id\": {\n" +
- " \"type\": \"integer\",\n" +
- " \"index\": \"not_analyzed\",\n" +
- " \"include_in_all\": false\n" +
- " },\n" +
- " \"title\": {\n" +
- " \"type\": \"string\",\n" +
- " \"store\": \"no\",\n" +
- " \"term_vector\": \"with_positions_offsets\",\n" +
- " \"analyzer\": \"ik_max_word\",\n" +
- " \"search_analyzer\": \"ik_max_word\",\n" +
- " \"include_in_all\": true\n" +
- " },\n" +
- " \"city\": {\n" +
- " \"type\": \"string\",\n" +
- " \"store\": \"no\",\n" +
- " \"term_vector\": \"with_positions_offsets\",\n" +
- " \"analyzer\": \"ik_max_word\",\n" +
- " \"search_analyzer\": \"ik_max_word\",\n" +
- " \"include_in_all\": true\n" +
- " },\n" +
- " \"location\":{\n" +
- " \"type\":\"geo_point\",\n" +
- " \"index\": \"not_analyzed\",\n" +
- " \"include_in_all\": false\n" +
- " }\n" +
- " }}";
- esClient.admin().indices().prepareCreate(indexName).execute().actionGet();
- PutMappingResponse response = esClient.admin().indices().preparePutMapping(indexName)
- .setType(indexType)
- .setSource(mapping)
- .get();
- if (!response.isAcknowledged()) {
- System.out.println("Could not define mapping for type [" + indexName + "]/[" + indexType + "].");
- } else {
- System.out.println("Mapping definition for [" + indexName + "]/[" + indexType + "] succesfully created.");
- }
- }
2.方法2此方法mapping易读。City类自己创建
- // 创建索引
- public static void createIndex(String indexName, String indexType) throws IOException {
- Settings settings = Settings.settingsBuilder()
- .put("cluster.name", "cluster_wubing")
- .build();
- InetAddress inetAddress = InetAddress.getByName("192.168.1.107");;
- Client esClient = TransportClient.builder().settings(settings).build()
- .addTransportAddress(new InetSocketTransportAddress(inetAddress, 9300));
- // 创建Mapping
- XContentBuilder mapping = createMapping(indexType);
- System.out.println("mapping:" + mapping.string());
- // 创建一个空索引
- esClient.admin().indices().prepareCreate(indexName).execute().actionGet();
- PutMappingRequest putMapping = Requests.putMappingRequest(indexName).type(indexType).source(mapping);
- PutMappingResponse response = esClient.admin().indices().putMapping(putMapping).actionGet();
- if (!response.isAcknowledged()) {
- System.out.println("Could not define mapping for type [" + indexName + "]/[" + indexType + "].");
- } else {
- System.out.println("Mapping definition for [" + indexName + "]/[" + indexType + "] succesfully created.");
- }
- }
- // 创建mapping
- public static XContentBuilder createMapping(String indexType) {
- XContentBuilder mapping = null;
- try {
- mapping = jsonBuilder().startObject()
- // 索引库名(类似数据库中的表)
- .startObject(indexType).startObject("properties")
- // ID
- .startObject("id").field("type", "long").endObject()
- // 城市
- .startObject("city").field("type", "string").endObject()
- // 位置
- .startObject("location").field("type", "geo_point").endObject()
- // 标题
- .startObject("title").field("type", "string").endObject()
- .endObject().endObject().endObject();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return mapping;
- }
2、向索引里添加数据
- // 添加数据
- public static Integer addIndexData(String indexName, String indexType) throws Exception {
- Client client = ElasticSerachUtil.getClient();
- List<String> cityList = new ArrayList<String>();
- City city1 = new City(1L, "北京", 116.395645, 39.929986, "中国人民站起来了,北京人民可以天天站在天安门广场吃烤鸭了");
- City city2 = new City(2L, "天津", 117.210813, 39.143931, "中国人民站起来了,天津人民可以天天在迎宾广场吃麻花了");
- City city3 = new City(3L, "青岛", 120.384428, 36.105215, "中国人民站起来了,青岛人民可以天天在!最后一次,不要错过今天");
- City city4 = new City(4L, "哈尔滨", 126.657717, 45.773225, "中国人民站起来了,哈尔滨人民可以天天站在索菲亚广场吃红肠了");
- City city5 = new City(5L, "乌鲁木齐", 87.564988, 43.840381, "中国人民站起来了,乌鲁木齐人民可以天天在人民广场啃羊腿了");
- City city6 = new City(6L, "三亚", 109.522771, 18.257776, "中国人民站起来了,三亚人民可以让青岛政府去丢吧,让他们创城去吧!");
- cityList.add(obj2JsonUserData(city1));
- cityList.add(obj2JsonUserData(city2));
- cityList.add(obj2JsonUserData(city3));
- cityList.add(obj2JsonUserData(city4));
- cityList.add(obj2JsonUserData(city5));
- cityList.add(obj2JsonUserData(city6));
- // 创建索引库
- List<IndexRequest> requests = new ArrayList<IndexRequest>();
- for (int i = 0; i < cityList.size(); i++) {
- IndexRequest request = client.prepareIndex(indexName, indexType).setSource(cityList.get(i)).request();
- requests.add(request);
- }
- // 批量创建索引
- BulkRequestBuilder bulkRequest = client.prepareBulk();
- for (IndexRequest request : requests) {
- bulkRequest.add(request);
- }
- BulkResponse bulkResponse = bulkRequest.execute().actionGet();
- if (bulkResponse.hasFailures()) {
- System.out.println("批量创建索引错误!");
- }
- return bulkRequest.numberOfActions();
- }
- public static String obj2JsonUserData(City city) {
- String jsonData = null;
- try {
- // 使用XContentBuilder创建json数据
- XContentBuilder jsonBuild = XContentFactory.jsonBuilder();
- jsonBuild.startObject().field("id", city.getId())
- .field("city", city.getCity())
- //注意纬度在前,经度在后 location类型
- .startArray("location").value(city.getLat()).value(city.getLon()).endArray()
- .field("title", city.getTitle())
- .endObject();
- jsonData = jsonBuild.string();
- System.out.println(jsonData);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return jsonData;
- }
3、最后创建search搜索和距离计算
- // 模糊查询
- public static void query(String query) throws Exception {
- Client client = ElasticSerachUtil.getClient();
- QueryStringQueryBuilder qsqb = new QueryStringQueryBuilder(query);
- // qsqb.analyzer("ik").field("title");
- qsqb.field("title");
- client.admin().indices().prepareRefresh().execute().actionGet();
- SearchResponse searchResponse = client.prepareSearch("testes").setTypes("xq").setQuery(qsqb)
- // .setScroll(new TimeValue(60000))
- .addFields("id", "title", "updatetime")
- // .addSort("updatetime", SortOrder.DESC)
- .addSort("_score", SortOrder.DESC)
- // .addHighlightedField("title")
- .setHighlighterEncoder("UTF-8").execute().actionGet();
- // 搜索耗时
- Float usetime = searchResponse.getTookInMillis() / 1000f;
- // 命中记录数
- Long hits = searchResponse.getHits().totalHits();
- System.out.println("查询到记录数=" + hits);
- for (SearchHit hit : searchResponse.getHits()) {
- // 打分
- Float score = hit.getScore();
- Integer id = Integer.parseInt(hit.getFields().get("id").value().toString());
- String title = hit.getFields().get("title").value().toString();
- System.out.println(title);
- }
- }
- // 获取附近的城市
- public static void testGetNearbyCities(Client client, String index, String type, double lat, double lon) throws ExecutionException, InterruptedException {
- SearchRequestBuilder srb = client.prepareSearch(index).setTypes(type);
- // srb.setPos
- // wx4g0th9p0gk 为北京的geohash 范围为lt(小于) 1500km内的数据
- QueryBuilder builder = geoDistanceRangeQuery("location")
- .point(lat,lon)//注意纬度在前,经度在后
- .from("0km")
- .to("10000km")
- .includeLower(true)
- .includeUpper(false)
- .optimizeBbox("memory")
- .geoDistance(GeoDistance.ARC);
- srb.setQuery(builder);
- // 获取距离多少公里 这个才是获取点与点之间的距离的
- //GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location");
- GeoDistanceSortBuilder sort = new GeoDistanceSortBuilder("location");
- sort.unit(DistanceUnit.KILOMETERS);//距离单位公里
- sort.order(SortOrder.ASC);
- sort.point(lat,lon);//注意纬度在前,经度在后
- srb.addSort(sort);
- SearchResponse searchResponse = srb.execute().actionGet();
- SearchHits hits = searchResponse.getHits();
- SearchHit[] searchHists = hits.getHits();
- System.out.println("北京附近的城市(" + hits.getTotalHits() + "个):");
- for (SearchHit hit : searchHists) {
- String city = (String) hit.getSource().get("city");
- String title = (String) hit.getSource().get("title");
- // 获取距离值,并保留两位小数点
- BigDecimal geoDis = new BigDecimal((Double) hit.getSortValues()[0]);
- Map<String, Object> hitMap = hit.getSource();
- // 在创建MAPPING的时候,属性名的不可为geoDistance。
- hitMap.put("geoDistance", geoDis.setScale(2, BigDecimal.ROUND_HALF_DOWN));
- System.out.println(city + "距离北京" + hit.getSource().get("geoDistance") + DistanceUnit.KILOMETERS.toString() + "---" + title);
- }
- }
4、写main方法测试
- public static void main(String[] args) throws Exception {
- Settings settings = Settings.settingsBuilder()
- .put("cluster.name", "cluster_wubing")
- .build();
- InetAddress inetAddress = InetAddress.getByName("192.168.1.107");;
- Client client = TransportClient.builder().settings(settings).build()
- .addTransportAddress(new InetSocketTransportAddress(inetAddress, 9300));
- String index = "testes2";
- String type = "xq2";
- //createIndex2(index, type);
- //addIndexData(index, type);
- double lat = 39.929986;
- double lon = 116.395645;
- long start = System.currentTimeMillis();
- testGetNearbyCities(client, index, type, lat, lon);
- query("政府");
- long end = System.currentTimeMillis();
- System.out.println((end - start) + "毫秒");
- client.close();
- }
搜索结果
ElasticSearch2.1 基于空间位置geo_query距离计算相关推荐
- 基于GPS与经纬度距离计算
基于GPS与经纬度距离计算 # -*- coding:utf-8 -*- # /usr/bin/pythonimport warnings warnings.filterwarnings(" ...
- c#语言+计算两个位置的距离,计算两个GPS坐标的距离 方法一 - C#语言
场景:已知两个GPS点的经纬度坐标信息.计算两点的距离. 1. 距离/纬度关系 GPS: 22.514519,113.380301 GPS: 22.511962,113.380301 距离:284.6 ...
- 图形处理(七)基于热传播的测地距离计算-Siggraph 2013
这里要跟大家分享的是2013年Siggraph上面的一篇paper,名为<Geodesics in Heat:A New Approach to Computing Distance Based ...
- 基于百度地图api实现计算目标点与自身位置的距离(js)
这里写自定义目录标题 导入api 获取自身定位 获取目标点定位 通过经纬度计算距离的函数 导入api 下面展示一些 内联代码片. ```javascript<script type=" ...
- 微信外卖小程序 怎么计算与客户的距离_微信小程序结合腾讯位置服务实现用户商家距离计算...
前言 小程序实操,距离计算总结. 思路 一共有两种方法,各有利弊: 1.利用小程序的wx.getLocation 方法得到用户的经纬度,然后用已知的商家的经纬进行计算; 2.利用腾讯地图位置服务cal ...
- 移动端H5 腾讯地图sdk 当前位置 地址你解析 距离计算
<template><view class="content"><view><input class="uni-input&qu ...
- Java实现对某一时刻GPS中圆轨道卫星的空间位置计算
在上两文中给出了Java编程实现对RINEX格式的观测值文件和广播星历文件的读取(读取观测值文件链接https://blog.csdn.net/qq_40449816/article/details/ ...
- c#语言+计算两个位置的距离,C#计算两个经纬度之间的距离
最近在项目中有一个功能需要计算两个经纬度之间的距离,在网上找了很多,也试了很多,下面的计算方法得出的结果是精度是最高,希望对大家有所帮助. private const double EARTH_RAD ...
- 基于js利用经纬度进行两地的距离计算
转自:http://www.storyday.com/html/y2009/2212_according-to-latitude-and-longitude-distance-calculation- ...
- html GPS坐标实现,JavaScript 实现GPS坐标点距离计算(两个经/纬度间的距离计算)...
在LBS(基于位置服务)的一些应用中,有时我们会需要计算两个用户或两个坐标点之间的距离.要解决这类问题,就要了解空间几何的概念并结合数学中在三角函数公式计算两点之间的值.本文介绍基于经度/纬度的,两个 ...
最新文章
- 装饰器的定义、语法糖用法及示例代码
- 喜得千金,升级做爸爸喽
- [转载] 英语科技论文写作——Difference between APAMLA
- docker部署openvas
- CSS三栏布局的四种方法
- 轻量级的Ajax解决方案——DynAjax:直接在客户端调用C#类的方法
- HALCON示例程序classify_image_class_mlp.hdev如何使用MLP分类器分割RGB图像
- C++复习总结(涵盖所有C++基本考点)!
- CSS3 响应式布局实例
- 证券投资深度学习_安信证券:“深度学习”开启新一轮计算模式变革
- 苹果Mac轻量级网页代码编辑器:​​​​​​​​​​​​Espresso
- 使用 requests 进行身份认证
- 在hbase 激活kerberos 下opentsdb的使用
- golang json string remove field
- linux命令从哪里敲,Linux 笔记本基于“敲打”的命令
- 信创终端违规外联案例分析及防控措施
- 分享一个好看的个人主页源码
- Delayed Project
- 网易详述8个月全过程:员工申请仲裁要求支付61万赔偿
- linux dhcpv6有状态配置,翻译:IPv6地址自动配置:有状态和无状态的区别