使用 ES 实现疫情地图或者外卖点餐功能(含代码及数据)

简介: 使用 ES 实现疫情地图或者外卖点餐功能(含代码及数据)

0、引言

疫情当下,大家几乎每天都在用疫情地图的相关功能,其中的核心功能即地理位置检索,使用 ES 可以非常轻松的实现,下面我简单说一下核心的几个功能如何设计和实现。


本文不涉及前段UI的设计和实现以及客户端调用代码,如果大伙儿需要,可以给我留言,需求量比较大的话可以考虑做一个完整项目开源出来,点赞支持下吧


PS:学习本文需要对 Elasticsearch 地理位置检索 的基本功能有一定的了解,推荐阅读:todo


本文案例中所使用的数据,可在文末下载。


1、功能模块

下图为疫情地图的基本木块,本文目的为将地理位置检索应用于项目落地,因此和核心功能无关的业务模块将不再罗列。主要的实现的功能如图所示

b4f49334f7fd4f358e76a5198a99b5fb.png


主要功能包含:

  • 行政地区信息录入
  • 机构信息
  • 健康码状态上报
  • 搜索附近的核酸检测机构(医院)
  • 查询某地区的确诊人数(行政区范围内)
  • 查询某地区的确诊人员分布
  • 查询某个医院所属的行政区
  • 统计各省份城市确诊人数


2、索引结构设计

2.1 地区索引

省市区联动是在很多场景下都是非常常见的,其表结构也非常简单,通过一个pid或者pcode即可保存起级联关系。

7152b7bffd884c02ac639d3161e3b8be.png

但是在地理位置检索时,只存在空间关系而不存在逻辑关系,不同的地理位置并不是通过关联字段来保存其关系的,因此在索引设计的时候,是否省市区是否采用结构化逻辑存储,取决于业务。单从地理位置检索上来分析,不管是省份、城市、地区还是街道,在地理位置坐标中均属于几何图形,因此无需结构化存储,每个_doc 保存一个geo_shape即为合理的方式。


我这里仍然是保留了省市区之间的逻辑关系,但是这一点对本文要实现的功能是没有用处的。建议在索引中为每一个省份、城市、地区、街道单独创建一个文档,使用polygon存储。


ES 支持仅支持基本的几何图形,并不支持不规则几何图形,省份地区这种图形如何存储?


其实不规则几何图形可以看成是边很多的多边形,当边的数量足够多,经可以足够精确的描述一个不规则多边形。这其实和你玩游戏的时候一样,一些需要显示曲线的场景,其实就是由无数个多边形来描述的,当边的数量足够多的时候,你就看不出的他是个多边形了。

cb767a5b2c0540148fb9a2d762f4073c.png


索引 mapping

PUT area
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      },
      "city": {
      "properties": {
          "location": {
            "type": "geo_shape"
          },
          "district": {
            "properties": {
              "location": {
                "type": "geo_shape"
              }
            }
          }
        }
      }
    }
  }
}


2.2 机构索引

机构可以是:医院、学校、桥梁、公司、隧道等任意单位,具体包含什么取决于你在做功能时想搜索到什么,一般机构为一个点坐标即可,即:geo_shape:point。为了简化代码,我这里只存储一个医院信息,也可以理解为核酸检测机构的网点。


索引 mapping 如下:

PUT hospital
{
  "mappings": {
    "properties": {
      "properties" : {
        "address" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "district" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "location" : {
          "type" : "geo_shape"
        },
        "lv" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}


2.3 人员信息索引(上报信息)

人员信息上报其实包含了如健康码、行程码(行程轨迹)、核酸检测报告、健康状态等信息,信息上报基本发生在门禁扫码登记、核酸检测结果发生时期等,行程轨迹上报时间可通过手机连接的基站发生变化而做出轨迹测算和上报。为了简化功能,我们人员的健康信息只保留一个状态字段:及健康或感染(确诊)。


索引 mapping:

PUT case_person
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date"
      },
      "location": {
        "type": "geo_shape"
      },
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "status": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}


3、实现

3.1 统计当日新增

这里只是做一个简单的统计,不再区分本土、外来、无症状等业务字段,统计当日新增,即表示满足

  • 确诊时间为当日
  • 状态为已确诊


两个条件的所有人员信息,代码如下:

GET case_person/_search
{
  "size": 0, 
  "query": {
    "bool": {
      "must": [
        {"range": {
          "date": {
            "gte": "now/d"
          }
        }},
        {
          "term": {
            "status.keyword": {
              "value": "确诊"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "today_add": {
      "value_count": {
        "field": "status.keyword"
      }
    }
  }
}


3.2 查询周边的确诊病例

查询周边确诊病例或者查询所在行政区的确诊病例,可应用如判断所属地区是否属于中高风险地区等业务,实现起来也非常简单。只需提供两个条件

  • 当前所处经纬度坐标
  • 搜索半径


如果是在APP中,当前所处坐标直接通过调用SDK中提供的位置接口即可获取,如果是用于测试,可通过百度地图提供的开放接口在地图上选点获取坐标。操作步骤为:

image.png


滚动页面,找到页面中开发文档部分,点击坐标拾取器

a7c9aecd88a343d59f326d0080d171a8.png

此时,地图中鼠标经过处便会显示实时坐标:

893a3d71b8194c4b8295f52774404462.png

5941044c00e34bae85fefc286e853327.png


可以在地图中选出自己心仪的坐标,模拟自己当前所处位置。比如我当前所处位置经纬度为:

  • “lon”:116.238334,
  • “lat”:39.900112


以图中定位的永辉超市为圆心,半径三公里,搜索到了 八角游乐园、八宝山、玉泉路、五棵松四个地铁站(这里地铁站可以看做是确认病例),即三公里范围内有四个确诊病例。

019976c290a749678dadc9690bc8b8c7.png


这样的搜索,同样可用于搜索附近的核酸检测机构:代码如下:

14df1f3f51a74e16855e16f7bc0d98b8.png


3.2 搜索指定区域内的指定单位

搜索指定区域内单位,可以搜索各种单位,也可以对各个行政地区进行搜索。

比如搜索北京市-海淀区内所有核酸检测机构:

6c986cc35634456f9ba87a78fabb48ff.png


代码如下:

GET province_bak/_search
{
  "query": {
    "term": {
      "name.keyword": {
        "value": "海淀区"
      }
    }
  }
}
GET hospital/_search
{
   "_source": {"include":["name","district"]},
  "query": {
    "geo_shape": {
      "location": {
        "indexed_shape": {
          "index": "province_bak",
          "id": "110108",
          "path": "location"
        },
        "relation": "within"
      }
    }
  }
}


相关文章
|
6月前
|
测试技术 开发工具 UED
什么是农场游戏系统开发规则玩法/详细需求/案例详情/源码项目
明确定义游戏概念和目标**: - 确定农场游戏系统的主题和核心玩法,明确目标用户群体,并设定明确的游戏目标和规则。
|
6月前
|
安全 区块链
区块链农场游戏系统开发运营版/玩法详情/规则方案/案例设计/项目源码
Developing a blockchain farm game system is an interesting and challenging task. Here is a design solution that can help you get started developing such a system
dapp预约抢单排单互助系统开发逻辑详细/功能说明/案例分析/方案规则/源码出售
Allow users to register accounts and verify their identities to ensure that the identities of participants are valid and authentic.
|
2月前
|
Web App开发 编解码 数据可视化
8月更新速递丨暑气未散,热情不减!EasyV产品、组件、模板升级优化不停~ EasyV数字孪生
暑气未消,初秋已至,我们在8月对产品进行了多项优化:「帮助中心」升级为「可视化学院」,涵盖视频、文档、社区等内容,助力高效学习;帮助文档检索能力升级,精准搜索;新增组件版本更新日志,快速掌握变化;引入产品反馈模块,解决疑难问题;新增吸色笔等功能,提升设计体验;优化项目过滤器,提高操作效率;上线文字转语音组件,丰富展示场景;新增多种模板素材,满足多样化需求。诚邀您加入EasyV产研社,共同探讨可视化产品的发展与未来。
|
6月前
|
JavaScript Java 测试技术
基于微信小程序的外卖点餐系统的设计与实现(源码+lw+部署文档+讲解等)
基于微信小程序的外卖点餐系统的设计与实现(源码+lw+部署文档+讲解等)
NFT卡牌游戏链游系统开发(开发方案)/详情规则/成熟技术/设计界面/案例项目/源码程序
NFT (Non Homogeneous Token) card chain game refers to a game based on blockchain technology where NFT is used as the card in the game. NFT is a unique and non interchangeable digital asset that can represent various virtual cards, props, or characters in the game.
|
数据库 开发工具 开发者
农场牧场养殖系统app合成养成模式玩法功能开发源码规则解析
农场牧场养殖系统app合成养成模式玩法功能开发源码规则解析
|
SQL 前端开发 JavaScript
基于php开发的外卖点餐网站
一个基于php的外卖订餐网站,包括前端和后台。
109 0
|
开发者
Jogger跑鞋零卷项目系统开发/方案详细/规则玩法/源代码案例/功能说明
针对Jogger跑鞋零卷项目系统开发/方案详细/规则玩法/源代码案例/功能说明进行介绍。
|
Rust 定位技术 区块链
区块链农场养殖类游戏模式玩法及开发源码示例
区块链农场养殖游戏是一个去中心化的虚拟农场游戏,玩家可以在游戏中体验种植、养殖的乐趣。游戏中的农场是一个数字资产,可以用来购买土地、种子、化肥、农药等物品,并通过种植、养殖动物获得收益。