elasticsearch 中的地理信息存储, 有geo_point形式和geo_shape两种形式

此篇只叙述geo_point,

地理位置需要声明为特殊的类型, 不显示在mapping中定义的话, 需要

{
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
},
"tag" : ["food", "family"],
"text" : "my favorite family restaurant"
}
}

如果仍然要显示的在mapping中定义, 则需要将其声明为 geo_point格式

{
"pin" : {
"properties" : {
"location" : {
"type" : "geo_point"
}
}
}
}

es的类型有: string, long, date, geo_point, 以后知道了在补充, text(for binary),

  range(integer_range, float_range, long_range, double_range, date_range)

  boolean, geo_point, geo_shape, ip, keyword, nested, token_count.. 可以参见这儿

多说一句: location的数据存放有3种形式:

  

    1), location: lat + "," + lon    // 最开始用的这个, 但是做 geoHashCellQuery查询测试时, 报错了
  2) location: {       "lat": ...,
      "lon": ...    
    }               // 这个是我使用的导入方式
  3), location: [lon, lat]      // 这个没用, 没测试, 没发言权

1, 导入查询数据, 使用的建立mapping的方式, 因为需要声明ik分词器

package com.iwhere.geosearch;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.yaml.snakeyaml.tokens.StreamStartToken; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; /**
* 从json文件中导入数据到es中
* @author 231
*
*/
public final class ImportData { private TransportClient client; @Test
public void test1() throws Exception {
createMapping("test", "catchModel");
importData("test", "catchModel");
System.out.println("success");
} /**
* 插入https://www.elastic.co/blog/geo-location-and-search的测试数据
* @throws Exception
*/
@Test
public void test2() throws Exception {
String index = "geo";
String type = "test";
BulkRequestBuilder prepareBulk = client.prepareBulk();
for (int i = 0; i < 50; i++) {
XContentBuilder source = getJson(40 + i, -71.34 + i, "my favorite family restaurant");
prepareBulk.add(client.prepareIndex(index, type).setSource(source));
}
BulkResponse response = prepareBulk.execute().actionGet();
} public XContentBuilder getJson(double lat, double lon, String text) throws IOException {
return XContentFactory.jsonBuilder()
.startObject()
.startObject("pin")
.startObject("location").field("lat", lat).field("lon", lon).endObject()
.field("tag", "food", "family")
.field("text", text)
.endObject()
.endObject();
} /**
* 导入数据
* @throws Exception
*/
public void importData(String index, String type) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(new File("D://catchModel.json")));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine()) != null) {
sb.append(line);
} BulkRequestBuilder prepareBulk = client.prepareBulk();
JSONArray parseArray = JSON.parseArray(sb.toString());
for (Object object : parseArray) {
// 强转为map, 否则报错 the number of object passed must be even
Map<String, Object> source = (Map<String, Object>) object;
// IndexResponse response = client.prepareIndex(index, type).setSource(source).get();
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("taskName", source.get("taskName"))
.field("sessionId", source.get("sessionId"))
.field("geoNum", source.get("geoNum"))
.field("geoLevel", source.get("geoLevel"))
.field("createTime", source.get("createTime"))
.field("endTime", source.get("endTime"))
.startObject("location").field("lat", source.get("lbLat"))
.field("lon", source.get("lbLng"))
// .field("location", source.get("lbLat") + "," + source.get("lbLng"))
// XContentFactory.jsonBuilder()
// .startObject()
// .field("lat", source.get("lbLat"))
// .field("lon", source.get("lblng"))
// .endObject())
.endObject();
prepareBulk.add(client.prepareIndex(index, type).setSource(xContentBuilder));
}
BulkResponse response = prepareBulk.get();
System.out.println(response);
} /**
* 创建mapping, 添加ik分词器等, 相当于创建数据库表
* 索引库名: indices
* 类型 : mappingType
* field("indexAnalyzer", "ik"): 字段分词ik索引
* field("searchAnalyzer", "ik"): ik分词查询
* @throws Exception
*/
public void createMapping(String indices, String type) throws Exception { // 创建index
Map<String, Object> settings = new HashMap<>();
settings.put("number_of_shards", 4); // 分片数量
settings.put("number_of_replicas", 0); // 复制数量, 导入时最好为0, 之后2-3即可
settings.put("refresh_interval", "10s");// 刷新时间 CreateIndexRequestBuilder prepareCreate = client.admin().indices().prepareCreate(indices);
prepareCreate.setSettings(settings); // 创建mapping
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject(type)
// .startObject("_ttl")//有了这个设置,就等于在这个给索引的记录增加了失效时间,
// //ttl的使用地方如在分布式下,web系统用户登录状态的维护.
// .field("enabled", true)//默认的false的
// .field("default", "5m")//默认的失效时间,d/h/m/s 即天/小时/分钟/秒
// .field("store", "yes")
// .field("index", "not_analyzed")
// .endObject()
// .startObject("_timestamp")//这个字段为时间戳字段.即你添加一条索引记录后,自动给该记录增加个时间字段(记录的创建时间),搜索中可以直接搜索该字段.
// .field("enabled", true)
// .field("store", "no")
// .field("index", "not_analyzed")
// .endObject()
.startObject("properties")
.startObject("taskName").field("type", "string").field("analyzer", "ik").field("searchAnalyzer", "ik").endObject()
.startObject("sessionId").field("type", "string").endObject()
.startObject("geoNum").field("type", "string").endObject()
.startObject("grandPaGeoNum").field("type", "string").endObject()
.startArray("sonGeoNum").endArray()
.startObject("geoLevel").field("type", "long").endObject()
.startObject("state").field("type", "long").endObject()
.startObject("createTime").field("type", "date").endObject()
.startObject("endTime").field("type", "date").endObject()
.startObject("location")
.field("type", "geo_point").field("geohash_prefix", true).field("geohash_precision", "1km").endObject()/*.field("lat_lon", true)*/.endObject()
.endObject().endObject();
System.out.println(mapping.string());
// PutMappingResponse actionGet = client.admin().|indices().preparePutMapping(indices).setType(indices).setSource(mapping).execute().actionGet();
prepareCreate.addMapping(type, mapping);
CreateIndexResponse response = prepareCreate.execute().actionGet();
System.out.println(response);
} @Before
public void before() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/applicationContxt-escluster.xml");
client = context.getBean(TransportClient.class);
}
}

2, 地理位置查询

package com.iwhere.geosearch;

import java.net.InetSocketAddress;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceRangeQueryBuilder;
import org.elasticsearch.index.query.GeoPolygonQueryBuilder;
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
import org.elasticsearch.index.query.GeohashCellQuery.Builder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Before;
import org.junit.Test; /**
* 使用dsl查询
* @author 231
*/
public class JavaESGEO { private TransportClient client; /**
* Caused by: [test] QueryParsingException[Field [location] is not a geo_shape]
   * 报错, 没运行出来
*/
@Test
public void testGeoShapeQuery() {
GeoShapeQueryBuilder geoShapeQuery = QueryBuilders.geoShapeQuery("location", ShapeBuilder.newMultiPoint()
.point(0, 0)
.point(0, 10)
.point(10, 10)
.point(10, 0)
.point(0, 0)
, ShapeRelation.WITHIN);
System.out.println(geoShapeQuery); SearchResponse response = client.prepareSearch("geo")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(geoShapeQuery).get();
} /**
* Caused by: java.lang.IllegalStateException: Shape with name [AVqw3mb-kOe4Yke4p-lh] found but missing shape field
*/
@Test
public void testGeoShapeQuery1() {
GeoShapeQueryBuilder queryBuilder = QueryBuilders.geoShapeQuery(
"model.location", // field
"AVqxrMyikOe4Yke4p_Wx", // id of document
"catchModel", ShapeRelation.WITHIN) // type, relation
.indexedShapeIndex("test") // name of index
.indexedShapePath("location"); // filed specified as path
SearchResponse response = client.prepareSearch()
.setQuery(queryBuilder).execute().actionGet();
String string = response.getHits().getHits().toString();
System.out.println(string);
} /**
* 使用 BoundingBoxQuery进行查询
*/
@Test
public void testGeoBoundingBoxQuery( ){
GeoBoundingBoxQueryBuilder queryBuilder = QueryBuilders.geoBoundingBoxQuery("location")
.topRight(40.0, 117)
.bottomLeft(39.9, 116);
SearchResponse searchResponse = client.prepareSearch("test")
.setQuery(queryBuilder).get();
System.out.println(searchResponse);
System.err.println(searchResponse.getHits().totalHits());
} /**
* distance query 查询
*/
@Test
public void testDistanceQuery() {
GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location")
.point(40, 116.5)
.distance(20, DistanceUnit.KILOMETERS)
.optimizeBbox("memory")
.geoDistance(GeoDistance.ARC);
SearchResponse response = client.prepareSearch("geo", "test")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(queryBuilder).execute().actionGet();
System.out.println(response);
System.err.println(response.getHits().totalHits());
} /**
* 环形查询
*/
@Test
public void testDistanceRangeQuery() {
GeoDistanceRangeQueryBuilder queryBuilder = QueryBuilders.geoDistanceRangeQuery("location")
.point(40, 116.5) // 中心点
.from("20km") // 内环
.to("25km") //外环
.includeLower(true) // 包含上届
.includeUpper(true) // 包含下届
.optimizeBbox("memory") // 边界框
.geoDistance(GeoDistance.SLOPPY_ARC);
SearchResponse response = client.prepareSearch("test")
.setSearchType(SearchType.DFS_QUERY_AND_FETCH)
.setQuery(queryBuilder).execute().actionGet();
System.out.println(response);
System.out.println(response.getHits().totalHits());
} /**
* 多边形查询
*/
@Test
public void testPolygonQuery() {
GeoPolygonQueryBuilder queryBuilder = QueryBuilders.geoPolygonQuery("location")
.addPoint(39, 116)
.addPoint(39, 117)
.addPoint(40, 117);
SearchResponse response = client.prepareSearch("test", "geo")
.setQuery(queryBuilder).get();
System.out.println(response);
System.err.println(response.getHits().totalHits());
} /**
* geoHash查询
* 要使用, 需要先开启
* "location": {
"type": "geo_point",
"geohash_prefix": true,
"geohash_precision": "1km" // 精度, 可在mapping中指定, 也可在代码中指定
*/
@Test
public void testGeoHashCellQuery() {
Builder precision = QueryBuilders.geoHashCellQuery("location",
new GeoPoint(39.9, 116))
.neighbors(true)
.precision(3);
SearchResponse response = client.prepareSearch("test")
.setQuery(precision).get();
System.out.println(response);
System.err.println(response.getHits().totalHits());
} @Before
public void testBefore() {
Settings settings = Settings.settingsBuilder().put("cluster.name", "wenbronk_escluster")
.put("client.transport.sniff", true).build();
client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(new InetSocketAddress("192.168.50.37", 9300)));
System.out.println("success to connect escluster");
}
}

其他配置信息见: spring整合java一章

基础数据从mongodb中拷贝来的, 在github有一个小量的数据

elasticsearch 导入基础数据并索引之 geo_point的更多相关文章

  1. elasticsearch 导入基础数据并索引之 geo_shape

    我们看到的图形, 实际是由点来完成的, 有2种类型的格子模型可用于地理星座, 默认使用的是geoHash, 还有一种4叉树(quad trees), 也可用于 判断形状与索引的形状关系 1), int ...

  2. docker-compose 构建mongodb并导入基础数据示例

    使用docker-compose构建mongodb服务并导入基础数据示例. 1.文件目录结构 ——mongo/ |——docker-compose.yml |——mongo-Dockerfile |— ...

  3. (转)淘淘商城系列——导入商品数据到索引库——Service层

    http://blog.csdn.net/yerenyuan_pku/article/details/72894187 通过上文的学习,我相信大家已经学会了如何使用Solrj来操作索引库.本文我们将把 ...

  4. Elasticsearch-基础介绍及索引原理分析(转载)

    最近在参与一个基于Elasticsearch作为底层数据框架提供大数据量(亿级)的实时统计查询的方案设计工作,花了些时间学习Elasticsearch的基础理论知识,整理了一下,希望能对Elastic ...

  5. Elasticsearch-基础介绍及索引原理分析

    介绍 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 L ...

  6. Logstash学习之路(二)Elasticsearch导入json数据文件

    一.数据从文件导入elasticsearch 1.数据准备: 1.数据文件:test.json 2.索引名称:index 3.数据类型:doc 4.批量操作API:bulk {"index& ...

  7. 用 Spark 为 Elasticsearch 导入搜索数据

    越来越健忘了,得记录下自己的操作才行! ES和spark版本: spark-1.6.0-bin-hadoop2.6 Elasticsearch for Apache Hadoop 2.1.2 如果是其 ...

  8. Solr学习笔记之3、Solr dataimport - 从SQLServer导入数据建立索引

    Solr学习笔记之3.Solr导入SQLServer数据建立索引 一.下载MSSQLServer的JDBC驱动 下载:Microsoft JDBC Driver 4.0 for SQL Server ...

  9. [搜索]ElasticSearch Java Api(一) -添加数据创建索引

    转载:http://blog.csdn.net/napoay/article/details/51707023 ElasticSearch JAVA API官网文档:https://www.elast ...

随机推荐

  1. 练习并熟练掌握交互式 SQL 语言

    哈工大数据库系统 实验:练习并熟练掌握交互式 SQL 语言   实验目的:基于给定的 OrderDB 数据库, 练习并熟练掌握交互式 SQL 语言实验环境:sql sever 2008 附:Order ...

  2. PhpStorm 注册相关

    网址 http://idea.lanyus.com/ 最新(2017年9月)PhpStorm 2017.3 .WebStorm 2017.2.5.PyCharm  2016.3激活方式 打开网址 ht ...

  3. 【commons-io】File对文件与目录的处理&FileUtis,IOUtils,FilenameUtils工具的使用

    -------------------File的使用-------------- 1.File类对文件的处理 1.1目录结构:  1.2测试对文件Test.txt处理: // 测试文件 @Test p ...

  4. Devexpress VCL Build v2014 vol 14.2.4 发布

    What's New in 14.2.4 (VCL Product Line)   New Major Features in 14.2 What's New in VCL Products 14.2 ...

  5. KbmMW 4.30.00 发布

    今天早上,KbmMW发布了4.30.00 版,这个版本开始支持XE4 的WIN/WIN64/OSX. 暂时不支持ios开发,同时加强了通过JSON 的对象序列化.还有就是解决了我提交的几个有关 汉字处 ...

  6. java中配置自定义拦截器中exclude-mapping path是什么意思?

    <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/>//过滤全部请求 & ...

  7. 2018.10.04 NOIP模拟 航班(tarjan+树形dp)

    传送门 考场上自己yy了一个双连通只有40分. 然后换根dp求最长路就行了. 代码

  8. 2018.08.21 bzoj4668: 冷战(并查集+启发式合并)

    传送门 可以发现需要维护连通性和两点连通时间. 前者显然是并查集的常规操作,关键就在于如何维护两点的连通时间. 然后会想到这个时候不能用路径压缩了,因为它会破坏原本树形集合的结构,因此可以启发式按si ...

  9. 着重基础之—Spring Boot 编写自己的过滤器

    Spring Boot 编写自己的"过滤器" 又好久没有写博客进行总结了,说实话,就是 "懒",懒得总结,懒得动.之所以写这篇博客,是因为最近对接公司SSO服务的时候,需要自定义拦 ...

  10. arduino空调遥控器

    参考:http://www.arduino.cn/thread-3487-1-1.html http://www.arduino.cn/thread-3618-1-1.html 注意1:有金属外壳的一 ...