elasticsearch存储经纬度且按照范围进行查询

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"
                }
            }
        ]
    }
}
posted @ 2024-05-21 17:18  实习小生  阅读(327)  评论(0编辑  收藏  举报