行政区边界数据常被视为一份静态 GeoJSON:导入一次,按名字或编码查到就结束。但把同一套边界接入 Elasticsearch、MongoDB、PostGIS 和应用搜索后,真正的发布对象不再只是文件,而是 geometry、中心点、空间索引、嵌套关系、导入脚本与修复日志组成的一套契约。Vietnamese Provinces Database v4.2.0 的官方发布提供了一个具体案例:它同时加入 Elasticsearch 与 MongoDB 的 GIS 数据发布,并把上游无效 ward geometry 的检查和修复放进生成管线。

关键不在于选择某个数据库,而在于防止每个分发端各自拥有不同的边界真相。一个 API 能按名称搜到行政区,不表示地图的多边形有效;一个 MongoDB 集合有 2dsphere index,也不表示 geoIntersects 返回的结果与 Elasticsearch 或 PostGIS 一致。发布应把 schema、geometry validity、索引、导入结果和跨端查询一起验收。

可核查事实

  • 官方 GitHub release 显示 Vietnamese Provinces Database v4.2.0 于 2026 年 8 月 2 日发布。

  • 该版本新增 Elasticsearch 数据集;provinces index 有 34 个省级文档,provinces-gis 也有 34 个文档,并包含省和 ward 的 bounding box 与 GeoJSON polygon。

  • 发布说明称 SearchKeywords 预先计算了编码、无音调名称、英文名称和 codeName,用于 full-text search 与 autocomplete。

  • provinces-gis 支持 geo_shape geometry 与 geo_point center,数据按 NDJSON bulk format 提供,可直接用于 Elasticsearch Bulk API。

  • MongoDB 新增 provinces-gis(34 个文档)和独立的 wards-gis(3,321 个文档);后者保留 ProvinceCode 用于 join。

  • 官方说明将 ward GIS 拆为独立 collection,以避免嵌入省级文档可能触及 16MB BSON 限制;以 Hanoi 500 多个 ward 为例,并提升 ward 级空间查询能力。

  • 两个 MongoDB collection 都在 GIS.GeometryGIS.Center 上建立 2dsphere indexes,支持 $geoIntersects$near$geoWithin

  • 该版本用 PostGIS 链 ST_CollectionExtract(ST_MakeValid(ST_GeomFromText(geom_wkt, 4326)), 3) 修复自相交等无效 ward geometry;生成时自动运行、记录审计日志且幂等。

  • 发布说明称有效 geometry 才导出到 PostgreSQL、MySQL、MSSQL、GeoJSON、Elasticsearch 和 MongoDB,并将 ward GIS 分成 8 个部分配合 manifest 导入。

这些事实来自项目 release note,反映该项目的数据模型和发布过程;它们不是任何国家行政边界的权威法律声明,也不能替代针对具体应用的来源核验。

核心机制

多格式空间发布应由一份权威 geometry 资产驱动,随后派生搜索索引、NoSQL collection 和文件导出。每个派生产物都要可回溯到同一数据版本、同一修复规则和同一坐标参考。把几何修复放入生成流程的意义在于:发现上游错误后,不靠某个客户端临时容错,而是生成可复现的修复记录并让所有出口同步更新。

索引是另一部分合同。Elasticsearch 的 geo_shape 和 MongoDB 的 2dsphere 都能执行空间过滤,却拥有不同的写入、mapping 和查询语义。团队应将“索引创建成功”与“典型空间谓词结果一致”分开验证,并记录分发端是否保留 geometry、bbox、center、行政编码和版本标识。

GIS 场景

设想公共服务平台要按行政区提供地址匹配、附近设施和边界叠加。搜索页面使用 Elasticsearch autocomplete,地图服务用 GeoJSON,移动端附近查询走 MongoDB,统计系统使用 PostGIS。发布流水线首先固定 province/ward code、名称、geometry、bbox、center 和数据版本;随后生成各端产物并执行同一组 AOI 查询。若某一 ward 在 Elasticsearch 命中、MongoDB 空间相交却未命中、地图上显示自相交,版本不能进入生产。

对于行政调整,属性变化和 geometry 变化也要分开记录。名称或层级变化可不改边界;边界变化则必须带来源文件、effective date、旧新范围差异和受影响索引清单。这样搜索结果、地图表现和统计口径才能在同一版本下解释。

技术路径

先设置输入质量门槛。验证 CRS、geometry type、闭合环、self-intersection、空值、bbox、center、行政编码和父子关系。对几何修复保留原始 WKT、修复后 geometry、所用函数/版本、原因和审计 ID;幂等性要通过重复生成比较输出哈希来确认。

再设置派生质量门槛。为 Elasticsearch 检查 mapping、bulk import 数量、nested ward 查询、全文检索和 geo_shape;为 MongoDB 检查 collection 数量、2dsphere index、$geoIntersects/$near/$geoWithinProvinceCode join;为 GeoJSON 和关系库检查 feature 数、编码、CRS 与范围。每项检查选定固定 AOI、名称和行政代码样本,保存命中集和版本。

最后执行跨端回归。将同一 AOI 和边界相切的 AOI 分别投到每个端点,比较命中 code 集合,而不是只比较数量。把索引构建、导入时间、失败记录和 manifest 一并归档。只有 geometry 有效、导入完整、跨端结果可解释时,才更新公开下载和线上服务。

风险边界

ST_MakeValid 解决几何有效性,不判断行政边界是否符合权威法定范围;修复可能改变几何结构,因此仍需记录原始数据和人工复核规则。bbox 和 center 是索引辅助信息,不能替代精确的 geo_shape 或 polygon 谓词。不同存储引擎的边界包含、精度和坐标处理存在差异,必须以项目定义的测试 AOI 和容差验证。

行政区数据还涉及生效日期、许可、名称变体和语言。搜索友好的无音调名称不应覆盖法定名称;历史查询需要明确请求的是当前边界还是某一时点的边界。

检查清单

  1. 为每个 province/ward 保存编码、名称、层级、CRS、geometry、bbox、center、有效期和源版本。

  2. 在派生前验证 geometry,并为修复保存原始值、规则、审计日志和可重复生成证据。

  3. 校验 Elasticsearch mapping、NDJSON 导入、全文/嵌套查询及 geo_shape/geo_point 结果。

  4. 校验 MongoDB collection、2dsphere indexes、空间谓词与 ProvinceCode join。

  5. 用相同 AOI 在搜索、NoSQL、关系库和 GeoJSON 端比较命中行政编码集合。

  6. 将分片导入与 manifest、行数、索引状态和失败项目绑定到版本。

  7. 区分属性变更和边界变更,并为历史和现行边界保留明确的时间语义。

结论

行政区边界进入搜索与 NoSQL 后,数据工程的重点是让每个出口共享同一份空间真相。用 geometry validity、索引语义、导入 manifest 和跨端 AOI 回归组成发布门槛,才能让名称搜索、附近查询和地图叠加在同一版本下可靠协作。

参考来源

  1. Vietnamese Provinces Database v4.2.0 官方发布说明:https://github.com/thanglequoc/vietnamese-provinces-database/releases/tag/v4.2.0