PostGIS与ES怎么选?空间查询谁更强?

GIS基础理论
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

“PostGIS与ES怎么选?空间查询谁更强?”这个问题在很多 WebGIS、位置检索、POI 搜索、轨迹筛选和空间分析项目里都会遇到。简单说,PostGIS 更像“空间数据库与空间分析引擎”,ES 通常指 Elasticsearch,更像“全文检索与近实时搜索引擎”。如果只问空间查询谁更强,答案不能只看速度,而要看查询类型、数据规模、更新频率、空间关系复杂度、排序需求和后续分析链路。

引言:不要只用“快不快”判断 PostGIS 与 ES

很多 GIS 初学者会把问题简化成:PostGIS 空间查询快,还是 ES 空间查询快?这个问法不够准确。因为 PostGIS 与 ES 的空间能力面向的场景不同。

PostGIS 是 PostgreSQL 的空间扩展,核心优势是标准空间数据管理、空间关系判断、空间分析、拓扑运算、投影转换和复杂 SQL 组合查询。ES 的优势是海量文本检索、条件过滤、相关性排序、聚合统计和近实时搜索。

在实际项目里,PostGIS与ES怎么选,通常取决于你的主要需求:

  • 如果你要做严谨的空间关系判断、缓冲区分析、叠加分析、面积长度计算,优先考虑 PostGIS。
  • 如果你要做 POI 名称搜索、地址关键词检索、地图框选后按热度排序,ES 更合适。
  • 如果你既要空间分析,又要全文检索,常见方案是 PostGIS 存主数据,ES 做搜索索引。
PostGIS与ES怎么选 空间查询谁更强对比流程图
PostGIS 与 ES 在空间查询、全文检索和空间分析场景中的典型分工。

背景:PostGIS 和 ES 分别擅长什么

PostGIS 的定位

PostGIS 是一个面向空间数据的关系型数据库扩展。它把点、线、面、多面、几何集合等空间对象作为数据库字段保存,并提供大量空间函数。

常见能力包括:

  • 空间关系判断:相交、包含、覆盖、接触、距离内等。
  • 空间分析:缓冲区、裁剪、叠加、合并、差集、相交结果生成。
  • 空间索引:常用 GiST、SP-GiST、BRIN 等索引类型。
  • 坐标系处理:通过 SRID 管理坐标参考系统,支持投影转换。
  • 复杂 SQL:可与属性过滤、分组统计、窗口函数、事务控制结合。

如果你的问题是“某个地块是否落在规划区内”“道路缓冲区 50 米内有哪些建筑”“两个面图层叠加后生成结果图层”,PostGIS 通常比 ES 更适合。

ES 的定位

ES 是 Elasticsearch 的常见简称,是面向搜索和分析的分布式引擎。它的核心能力不是传统 GIS 分析,而是快速检索、全文搜索、过滤、排序和聚合。

ES 支持空间字段,常见有两类:

  • geo_point:用于经纬度点,例如门店、车辆位置、用户位置。
  • geo_shape:用于线、面、多边形等复杂空间对象。

如果你的需求是“在地图当前视野内搜索名称包含咖啡的 POI,并按距离、评分、热度排序”,ES 通常很有优势。它可以把空间过滤、关键词搜索和排序聚合放在同一次搜索请求中。

原理:空间查询谁更强,要看查询类型

讨论 PostGIS 空间查询和 ES 空间查询,不能脱离具体查询类型。下面按 GIS 项目中最常见的几类查询来判断。

1. 范围过滤:两者都能做,但目标不同

范围过滤包括地图矩形框查询、圆形半径查询、多边形内查询等。例如“查询当前地图视野内的所有点”。

PostGIS 可以使用空间索引加速范围查询,例如:

SELECT id, name
FROM poi
WHERE geom && ST_MakeEnvelope(116.30, 39.85, 116.50, 40.00, 4326);

ES 也可以使用 geo_bounding_box 或 geo_distance 查询,例如用于点数据的地图视野过滤。

如果只是简单的地图框选 POI,并且还要配合关键词检索、分页和排序,ES 体验通常更好。如果后续还要进行空间叠加、精确空间关系判断或输出分析结果,PostGIS 更稳。

2. 空间关系判断:PostGIS 更强

空间关系判断是 GIS 数据库的核心能力。例如相交、包含、被包含、覆盖、接触等。

PostGIS 提供了成熟的空间关系函数:

  • ST_Intersects:判断两个几何对象是否相交。
  • ST_Contains:判断一个几何对象是否包含另一个。
  • ST_Within:判断一个几何对象是否在另一个内部。
  • ST_Touches:判断边界是否接触。
  • ST_Covers:判断覆盖关系,边界处理上与包含有所区别。

ES 的 geo_shape 也支持部分空间关系查询,例如 intersects、within、contains、disjoint,但它更偏向搜索过滤,不适合承担复杂空间分析流程。尤其当你需要生成新的几何结果、做叠加分析或严格处理拓扑关系时,PostGIS 更合适。

3. 距离查询:简单搜索 ES 方便,严谨计算 PostGIS 更可靠

距离查询常见于“附近的人”“附近门店”“车辆距离某点多少米”。ES 对点数据的 geo_distance 查询非常适合搜索业务,可以快速找出一定半径内的对象并按距离排序。

但如果涉及投影坐标、线面距离、最近点、路径附近对象、单位精度和复杂几何距离,PostGIS 更可靠。例如:

SELECT id, name
FROM hospitals
WHERE ST_DWithin(
  geom::geography,
  ST_SetSRID(ST_MakePoint(116.397, 39.908), 4326)::geography,
  3000
);

这里使用 geography 类型可以在经纬度数据上按米进行距离判断,适合 WGS84 经纬度数据的近似地球距离计算。对于小范围工程数据,也可以先投影到合适的平面坐标系,再用 geometry 计算。

4. 全文检索加空间过滤:ES 更强

如果你的核心需求是“搜索”,例如用户输入“朝阳公园附近咖啡店”,系统需要同时处理关键词、分词、模糊匹配、距离排序、评分排序和分页,那么 ES 更适合。

PostgreSQL 也有全文检索能力,但在大规模搜索、复杂相关性排序、多条件聚合和搜索体验优化方面,ES 通常更常见。

这类项目中,PostGIS 与 ES 怎么选的实用答案往往是:PostGIS 作为权威空间数据源,ES 作为面向前端搜索的索引层。

步骤:按项目需求选择 PostGIS 或 ES

步骤 1:先确认主需求是“分析”还是“搜索”

先不要急着选技术,先写出你的主要查询语句或业务问题。

  • 如果问题是“哪些地块与保护红线相交”,这是空间分析,优先 PostGIS。
  • 如果问题是“搜索名称包含学校的点,并按距离排序”,这是搜索,优先 ES。
  • 如果问题是“先搜索 POI,再基于行政区做统计分析”,可能需要 PostGIS + ES。

步骤 2:判断数据类型

不同空间数据类型会直接影响选择。

数据类型 更推荐 原因
POI 点数据 ES 或 PostGIS 简单点查询两者都可以;搜索排序强依赖 ES,空间分析强依赖 PostGIS。
道路、河流等线数据 PostGIS 线缓冲、相交、距离、网络前处理更适合在 PostGIS 中完成。
行政区、地块、规划面 PostGIS 面叠加、包含判断、面积统计、拓扑修复更依赖 PostGIS。
用户实时位置点 ES 或时序数据库 + PostGIS 高频搜索和看板可用 ES,历史轨迹分析仍可能需要 PostGIS。
带名称、地址、标签的 POI ES + PostGIS ES 负责搜索体验,PostGIS 保存权威几何和分析能力。

步骤 3:判断查询是否需要生成新的空间结果

这是非常关键的判断点。

如果查询只是“筛出符合条件的对象”,ES 和 PostGIS 都可以做。但如果查询需要生成新的几何对象,例如缓冲区、裁剪后的面、两个图层的交集结果,就应该选 PostGIS。

例如 PostGIS 可以直接生成缓冲区:

SELECT id, ST_Buffer(geom, 100) AS buffer_geom
FROM roads;

也可以生成两个图层的相交结果:

SELECT a.id AS parcel_id,
       b.id AS zone_id,
       ST_Intersection(a.geom, b.geom) AS intersect_geom
FROM parcels a
JOIN planning_zones b
ON ST_Intersects(a.geom, b.geom);

ES 不适合承担这类空间结果生产工作。

步骤 4:评估更新频率和一致性要求

PostGIS 是关系型数据库,事务、一致性、约束、外键、更新回滚等能力更完整。它适合保存权威数据。

ES 是近实时搜索引擎,文档写入后通常需要经过刷新才可被搜索到。对于搜索系统这很正常,但如果你的业务要求强一致,例如审批系统、资产登记系统、权属边界管理,不能只依赖 ES 作为唯一数据源。

推荐做法:

  • 权威空间数据保存在 PostGIS。
  • 需要搜索的字段同步到 ES。
  • ES 中保存用于检索的冗余字段,例如名称、地址、标签、坐标、行政区编码。
  • 数据修改以后通过任务队列、CDC 或定时同步更新 ES 索引。

步骤 5:为 PostGIS 建空间索引

很多人觉得 PostGIS 空间查询慢,原因不是 PostGIS 不行,而是没有正确建空间索引,或者查询写法导致索引没有被有效使用。

常见建索引方式:

CREATE INDEX idx_poi_geom
ON poi
USING GIST (geom);

查询后可以用 EXPLAIN 检查执行计划:

EXPLAIN ANALYZE
SELECT *
FROM poi
WHERE ST_Intersects(
  geom,
  ST_MakeEnvelope(116.30, 39.85, 116.50, 40.00, 4326)
);

如果执行计划中完全没有使用空间索引,需要检查字段类型、SRID、函数写法和统计信息。

步骤 6:为 ES 设计正确的空间字段

ES 中点数据一般使用 geo_point,面或线数据使用 geo_shape。字段类型一旦建错,后续查询会很麻烦,通常需要重建索引。

一个简化的 geo_point 映射示例:

{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "location": { "type": "geo_point" },
      "category": { "type": "keyword" }
    }
  }
}

如果你要做地图范围内的 POI 搜索,可以把名称、分类、行政区、坐标一起写入 ES。PostGIS 中仍然保存原始几何和完整业务表。

常见坑:PostGIS 与 ES 选型时最容易踩的错误

坑 1:把 ES 当成完整 GIS 空间数据库

ES 支持空间查询,但它不是完整的 GIS 空间分析平台。不要指望它替代 PostGIS 完成复杂叠加分析、几何修复、投影转换、面积统计和批量空间处理。

坑 2:PostGIS 中经纬度直接算米

很多新手直接在 EPSG:4326 经纬度坐标上用 geometry 计算距离或面积,结果会出现单位不符合预期的问题。经纬度的单位是度,不是米。

解决方式通常有两种:

  • 使用 geography 类型进行按米的距离计算。
  • 把数据投影到合适的平面坐标系,再进行距离和面积计算。

坑 3:空间索引建了但查询仍然慢

空间索引不是万能的。以下情况都可能导致查询慢:

  • 表数据量很大,但没有执行 ANALYZE 更新统计信息。
  • 查询条件写法让数据库无法有效使用索引。
  • 空间对象过于复杂,例如单个多边形有几十万节点。
  • 所有数据集中在很小范围内,空间索引选择性较差。
  • ST_Transform 被放在字段侧,导致索引难以命中。

坑 4:ES 中 geo_shape 数据过复杂

复杂面数据进入 ES 后,索引体积和查询成本可能明显上升。如果只是前端地图展示或空间分析,不一定要把完整复杂面都放进 ES。

可以考虑:

  • ES 中只存简化后的边界用于搜索过滤。
  • PostGIS 中保存高精度原始几何。
  • 前端展示使用矢量瓦片或专门的地图服务。

坑 5:双写 PostGIS 和 ES 后数据不一致

PostGIS + ES 架构很常见,但也容易出现数据不一致。比如 PostGIS 中 POI 已修改,ES 里仍是旧名称或旧坐标。

建议明确数据流:

  • PostGIS 是主库,ES 是索引。
  • 所有编辑先写 PostGIS。
  • 通过可靠同步机制更新 ES。
  • 在业务页面上区分“搜索结果”和“权威详情”。

方法比较:PostGIS 空间查询和 ES 空间查询怎么选

比较项 PostGIS ES
核心定位 空间数据库与空间分析 搜索引擎与检索分析
点附近查询 可靠,适合严谨计算 方便,适合搜索排序
面相交、包含判断 强,函数完整 可做过滤,但不适合复杂 GIS 分析
缓冲区、裁剪、叠加 强,推荐使用 不适合
全文检索 可用,但不是主要优势 强,适合关键词、分词、相关性排序
事务一致性 强,适合作为权威数据源 近实时,适合作为搜索索引
复杂 SQL 联表 不适合传统多表关系查询
典型应用 国土空间分析、规划审查、空间统计、数据质检 POI 搜索、附近检索、地图搜索框、日志地理聚合

如果只用一句话概括:PostGIS 空间查询更适合“算得准、关系复杂、结果可追溯”的 GIS 分析;ES 空间查询更适合“搜得快、体验好、排序灵活”的检索场景。

检查清单:项目选型前先问这 10 个问题

  • 你的核心需求是空间分析,还是关键词搜索?
  • 查询对象主要是点,还是线面和复杂多边形?
  • 是否需要生成新的几何结果,例如缓冲区、裁剪结果、叠加结果?
  • 是否需要严格事务、一致性和权限控制?
  • 是否需要中文分词、模糊搜索、相关性排序?
  • 是否需要按距离、热度、评分、业务权重混合排序?
  • 数据是否会频繁更新?更新后是否要求立即可查?
  • 空间坐标系是否统一?距离和面积单位是否明确?
  • 是否已有 PostGIS 主库,ES 是否只是索引层?
  • 慢查询是否已经通过索引、执行计划和数据简化排查过?

实用建议:不要为了“看起来架构先进”而强行上 ES。也不要因为 PostGIS 能做很多事,就把所有搜索体验都压在数据库上。先明确业务主线,再决定主库、索引和分析引擎的分工。

FAQ:PostGIS与ES怎么选的常见问题

PostGIS 空间查询一定比 ES 快吗?

不一定。对于简单点数据的附近搜索、地图框选和关键词过滤,ES 可能体验更好。对于复杂空间关系、线面计算、叠加分析和严谨空间结果生成,PostGIS 更强。空间查询谁更强,要看任务类型,而不是只看数据库名称。

ES 能不能完全替代 PostGIS?

通常不建议。ES 可以承担部分空间过滤和搜索任务,但不适合作为空间权威数据库。涉及坐标系管理、空间分析、复杂 SQL、事务一致性和数据质检时,PostGIS 更合适。

PostGIS + ES 架构适合哪些 WebGIS 项目?

适合 POI 搜索、地址检索、门店查询、地图搜索框、带空间过滤的业务检索系统。常见做法是 PostGIS 保存权威空间数据,ES 保存搜索索引,前端查询先走 ES,详情和分析再回到 PostGIS。

面数据应该放到 ES 的 geo_shape 里吗?

要谨慎。如果只是少量简单面,用 geo_shape 做空间过滤可以考虑。如果是大量复杂行政区、地块、规划面,建议 PostGIS 保存完整几何,ES 只保存必要的简化几何或属性索引。复杂面会增加 ES 索引体积和查询成本。

PostGIS 空间查询慢应该先优化什么?

先检查是否建立 GiST 空间索引,再用 EXPLAIN ANALYZE 看执行计划。然后检查 SRID 是否一致、空间对象是否过复杂、查询函数是否写在索引字段侧、统计信息是否更新。很多慢查询问题不是 PostGIS 本身慢,而是索引和数据组织方式不合理。

如果只做附近门店搜索,选 PostGIS 还是 ES?

如果门店数量不大、查询逻辑简单,PostGIS 足够。如果门店数量大,并且需要名称搜索、分类过滤、距离排序、营业状态、评分权重和分页体验,ES 更适合作为搜索层。权威门店数据仍建议保存在 PostGIS 或关系数据库中。

结论:空间分析选 PostGIS,搜索体验选 ES,复杂项目组合使用

PostGIS与ES怎么选,关键不是争论谁绝对更强,而是把任务拆清楚。PostGIS 擅长空间数据库、空间关系、空间分析和严谨计算;ES 擅长全文检索、空间过滤、排序聚合和近实时搜索。

对于 GIS 项目,推荐的判断原则是:

  • 需要 ST_Intersects、ST_Contains、ST_DWithin、ST_Buffer、ST_Intersection 等空间分析函数,优先 PostGIS。
  • 需要关键词搜索、模糊匹配、相关性排序、地图范围内快速检索,优先 ES。
  • 需要同时兼顾权威数据管理和搜索体验,采用 PostGIS + ES 组合架构。

所以,“PostGIS与ES怎么选?空间查询谁更强?”的实用答案是:空间分析能力 PostGIS 更强,搜索检索体验 ES 更强。真正稳定的 WebGIS 系统,往往不是二选一,而是让 PostGIS 做可靠的数据与分析底座,让 ES 做高效的搜索入口。