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

如何通过Go驱动或mgo/qmgo在MongoDB中存储地理空间数据

合规实现MongoDB地理空间数据操作的方案(Go语言)

两种依赖包都可以直接使用MongoDB官方提供的原生类型实现,完全不需要自定义非标准的GeoJSON结构体,属于官方推荐的合规实现方案:


1. 官方mongo-go-driver实现方案

官方驱动内置了全量GeoJSON类型,定义在go.mongodb.org/mongo-driver/bson/primitive包下,直接引用即可:

  • 支持的原生类型包括Point、LineString、Polygon、MultiPoint、MultiLineString、MultiPolygon、GeometryCollection,完全覆盖GeoJSON标准规范
  • 所有原生类型已经实现了BSON序列化/反序列化接口,可直接绑定到业务结构体字段

存储示例代码

import (
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
)

// 业务数据结构体
type Place struct {
    ID       primitive.ObjectID `bson:"_id,omitempty"`
    Name     string             `bson:"name"`
    Location primitive.Point    `bson:"location"`
}

// 写入地理空间数据
newPlace := Place{
    Name: "示例商圈",
    Location: primitive.Point{
        Type: "Point",
        Coordinates: []float64{116.3972, 39.9075}, // *注意坐标顺序严格为[经度, 纬度]*
    },
}
_, err := collection.InsertOne(ctx, newPlace)

地理索引创建示例

存储完成后需要创建地理空间索引才能正常查询:

// 创建2dsphere球面索引(绝大多数业务场景使用该类型即可)
indexModel := mongo.IndexModel{
    Keys: bson.D{{Key: "location", Value: "2dsphere"}},
}
_, err = collection.Indexes().CreateOne(ctx, indexModel)

范围查询示例

// 查询目标点周围5000米内的点位
filter := bson.M{
    "location": bson.M{
        "$near": bson.M{
            "$geometry": primitive.Point{
                Type: "Point",
                Coordinates: []float64{116.3972, 39.9075},
            },
            "$maxDistance": 5000, // 距离单位为米
        },
    },
}
var res []Place
err = collection.Find(ctx, filter).All(ctx, &res)

2. qmgo适配实现方案

qmgo基于官方mongo-go-driver封装,完全兼容官方原生GeoJSON类型,用法和官方驱动基本一致,仅API调用逻辑略有简化:

import (
    "github.com/qiniu/qmgo"
    "go.mongodb.org/mongo-driver/bson/primitive"
)

// 示例:查询指定多边形范围内的所有点位
filter := bson.M{
    "location": bson.M{
        "$geoWithin": bson.M{
            "$geometry": primitive.Polygon{
                Type: "Polygon",
                Coordinates: [][][]float64{
                    {
                        {116.3, 39.9},
                        {116.4, 39.9},
                        {116.4, 40.0},
                        {116.3, 40.0},
                        {116.3, 39.9}, // 多边形首尾坐标必须重合
                    },
                },
            },
        },
    },
}
var res []Place
err := qmgoClient.Database("业务库名").Collection("place").Find(ctx, filter).All(&res)

注意事项
  • 所有GeoJSON坐标必须严格遵循*[经度, 纬度]*的顺序,顺序颠倒会导致所有查询结果异常
  • 如果是平面地图低精度小范围查询场景,可以选择创建2d平面索引替代2dsphere球面索引
  • 复杂多要素组合的地理数据可以直接使用primitive.GeometryCollection类型存储和查询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:36:01