使用 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"
      }
    }
  }
}


相关文章
|
3月前
|
测试技术 开发工具 UED
什么是农场游戏系统开发规则玩法/详细需求/案例详情/源码项目
明确定义游戏概念和目标**: - 确定农场游戏系统的主题和核心玩法,明确目标用户群体,并设定明确的游戏目标和规则。
|
8月前
|
安全
dapp预约抢单排单互助系统开发逻辑详细/功能说明/案例分析/方案规则/源码出售
Allow users to register accounts and verify their identities to ensure that the identities of participants are valid and authentic.
|
9月前
|
安全
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.
|
9月前
|
安全 区块链
NFT元宇宙游戏链游戏统开发(智能合约开发详情)丨规则方案丨案例详细丨源码说明
The NFT metaverse refers to a digital asset trading platform that builds a virtual world based on blockchain technology. The development of a game chain game system is a process of developing gamified interactive experiences and social functions based on the NFT metaverse. By combining blockchain wi
|
10月前
|
存储 区块链 数据安全/隐私保护
Stepn跑鞋/Jogger慢跑者NFT链游铸造合成项目系统开发(正式版)/案例说明/方案介绍/逻辑项目/源码平台
链游是指基于区块链技术的游戏,也被称为区块链游戏或加密游戏。在传统游戏中,游戏数据通常由中心化的服务器控制和存储,而在链游中,游戏数据被存储在区块链网络中,所有的玩家都可以访问和验证这些数据。
|
10月前
|
数据库 开发工具 开发者
农场牧场养殖系统app合成养成模式玩法功能开发源码规则解析
农场牧场养殖系统app合成养成模式玩法功能开发源码规则解析
|
12月前
|
存储 缓存 安全
移动端的「基金地图」是怎么做的?
移动端的「基金地图」是怎么做的?
|
12月前
|
Rust 定位技术 区块链
区块链农场养殖类游戏模式玩法及开发源码示例
区块链农场养殖游戏是一个去中心化的虚拟农场游戏,玩家可以在游戏中体验种植、养殖的乐趣。游戏中的农场是一个数字资产,可以用来购买土地、种子、化肥、农药等物品,并通过种植、养殖动物获得收益。
|
数据可视化
【数据可视化】预制菜行业分析(二)——发展驱动因素
近年来,预制菜开始从大型连锁餐饮企业的中央厨房渗透到外卖餐饮平台,并逐渐从 B 端走向 C 端。消费者购买后只需要简单加工即可食用,省去了食材采购、处理步骤,具有便捷、高效、口味保持度高的特点。
|
Java 数据库连接 测试技术
校园外卖点餐系统——Day03【分类管理业务开发】
校园外卖点餐系统——Day03【分类管理业务开发】
108 0
校园外卖点餐系统——Day03【分类管理业务开发】