You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vapor框架中通过Fluent ORM直接执行PostgreSQL/SQL语句

在Vapor中为Geohash创建PostgreSQL索引的方案

一、直接通过PostgreSQL语句操作

1. 添加Geohash字段(若表中不存在)

假设你的目标表为locations,执行以下SQL添加存储geohash的字段:

ALTER TABLE locations ADD COLUMN geohash VARCHAR(20);

2. 创建Geohash索引

Geohash是字符串类型,使用B-tree索引即可满足前缀匹配、精确匹配等常见查询需求:

CREATE INDEX idx_locations_geohash ON locations USING btree (geohash);

3. (可选)批量生成Geohash(基于已有经纬度)

如果表中已有latitude(纬度)和longitude(经度)字段,可借助PostGIS扩展生成geohash:

-- 先安装PostGIS(若未安装)
CREATE EXTENSION IF NOT EXISTS postgis;

-- 批量更新生成geohash(这里指定精度为12位)
UPDATE locations SET geohash = ST_GeoHash(ST_MakePoint(longitude, latitude), 12);

二、在Vapor中执行原生SQL的两种方式

方式1:在路由/服务中直接执行

通过Vapor的Database对象调用raw方法执行原生SQL:

func setupGeohashIndex(_ req: Request) async throws -> HTTPStatus {
    // 添加字段
    try await req.db.raw("ALTER TABLE locations ADD COLUMN geohash VARCHAR(20);").run()
    // 创建索引
    try await req.db.raw("CREATE INDEX idx_locations_geohash ON locations USING btree (geohash);").run()
    return .ok
}

将该函数注册为路由即可触发操作。

方式2:通过迁移执行(推荐,便于版本管理)

创建自定义迁移类,将索引操作纳入Vapor的迁移流程:

struct AddGeohashIndexMigration: AsyncMigration {
    func prepare(on database: Database) async throws {
        try await database.raw("ALTER TABLE locations ADD COLUMN geohash VARCHAR(20);").run()
        try await database.raw("CREATE INDEX idx_locations_geohash ON locations USING btree (geohash);").run()
    }

    func revert(on database: Database) async throws {
        // 回滚操作:删除索引和字段
        try await database.raw("DROP INDEX IF EXISTS idx_locations_geohash;").run()
        try await database.raw("ALTER TABLE locations DROP COLUMN IF EXISTS geohash;").run()
    }
}

然后在configure.swift中注册迁移:

app.migrations.add(AddGeohashIndexMigration())

内容的提问来源于stack exchange,提问作者ScottyBlades

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:52:17