如何用Elasticsearch按经纬度范围查询?

摘要:elasticsearch存储经纬度且按照范围进行查询 背景: 我在客户那边有很多舆情事件数据,数据里面包含的是有经纬度的,项目需求是用户在系统中输入一个地址,系统就可以查询到该地址100米 500米 1000米范围内的事件信息,当然了还可
elasticsearch存储经纬度且按照范围进行查询 背景: 我在客户那边有很多舆情事件数据,数据里面包含的是有经纬度的,项目需求是用户在系统中输入一个地址,系统就可以查询到该地址100米 500米 1000米范围内的事件信息,当然了还可以输入事件的关键信息做模糊查询,所以我选择了使用es来存储引擎。 第一步: 创建ES索引 以下索引是测试环境数据 { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "content": { "type": "text", "analyzer": "ik_max_word" }, "location": { "type": "geo_point" }, "id": { "type": "keyword" } } } } 第一步: 数据同步 我使用flinkSQL搭配袋鼠云的chunjun来将数据库里面的事件数据写入到ES 下面是我写的flinkSQL脚本 -- 数据库表 CREATE TABLE `location_test` ( `id` VARCHAR, `content` VARCHAR COMMENT '内容', `lon` VARCHAR COMMENT '经度', `lat` VARCHAR COMMENT '纬度' ) WITH ( 'connector' = 'mysql-x', 'url' = 'jdbc:mysql://127.0.0.1:3306/xxx?useSSL=false&useInformationSchema=true&nullCatalogMeansCurrent=true&characterEncoding=UTF-8', 'table-name' = 'location_test', 'username' = 'xxx', 'password' = 'xxx', 'scan.fetch-size' = '1024' ); -- es索引 CREATE TABLE `location_geo_test` ( `id` VARCHAR COMMENT '主键', `content` VARCHAR COMMENT '内容', `location` ROW< `lon` VARCHAR, `lat` VARCHAR > COMMENT '经纬度', PRIMARY KEY (`id`) NOT ENFORCED ) WITH ( 'connector' = 'elasticsearch7-x', 'hosts' = '127.0.0.1:15287', 'index' = 'location_geo_test', 'username' = 'xxx', 'password' = 'xxx', 'sink.bulk-flush.max-actions' = '1024', 'sink.bulk-flush.interval' = '2000', 'sink.bulk-flush.max-size' = '5mb' ); INSERT INTO `location_geo_test` (SELECT `id`, `content`, (`lat`, `lon`) FROM `location_test`); flink任务执行完毕之后 查询es数据 { "took": 15, "timed_out": false, "_shards": { "total": 6, "successful": 6, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 3, "relation": "eq" }, "max_score": 1.0, "hits": [ { "_index": "location_geo_test", "_type": "_doc", "_id": "2", "_score": 1.0, "_source": { "location": { "lon": "120.165269", "lat": "30.312568" }, "id": "2", "content": "杭州市xxx" } }, { "_index": "location_geo_test", "_type": "_doc", "_id": "3", "_score": 1.0, "_source": { "location": { "lon": "120.163325", "lat": "30.271001" }, "id": "3", "content": "杭州市xxx" } }, { "_index": "location_geo_test", "_type": "_doc", "_id": "1", "_score": 1.0, "_source": { "location": { "lon": "120.165269", "lat": "30.312568" }, "id": "1", "content": "杭州市xxx" } } ] } } 第三步: 查询 { "query": { "geo_distance": { "location": { "lon": 120.165269, "lat": 30.312568 }, "distance": 1, "distance_type": "arc" } } } location:确定一个点; distance:确定一个半径,单位米 distance_type:确定一个图形的类型;一般是圆形,arc 结果 { "took": 5, "timed_out": false, "_shards": { "total": 6, "successful": 6, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 1.0, "hits": [ { "_index": "location_geo_test", "_type": "_doc", "_id": "2", "_score": 1.0, "_source": { "location": { "lon": "120.165269", "lat": "30.312568" }, "id": "2", "content": "杭州市xxx" } }, { "_index": "location_geo_test", "_type": "_doc", "_id": "1", "_score": 1.0, "_source": { "location": { "lon": "120.165269", "lat": "30.312568" }, "id": "1", "content": "杭州市xxx" } } ] } }