How to store geo-spatial data in MongoDB with Go driver or mgo/qmgo?

389 views Asked by At

I'm using MongoDB driver and mgo-forked qmgo in Go to operate MongoDB (version 5.x).

I have some geo-spatial data to store and query, and searched some articles and someone mentioned to create custom struct GeoJSON, others said another custom struct, but it's not official way and not consistent.

Is there any proper ways to store and query such data with Go packages?

2

There are 2 answers

1
Tom Slabbaert On

Assuming you'll want to query this data using geo qualities Mongo docs do specify this

To calculate geometry over an Earth-like sphere, store your location data as GeoJSON objects.

Basically the structure you want to save should match the spatial index requirements, so it should be in this structure:

<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

0
Mirusky On

A GeoJSON is a complex object to handle in Go since it changes according with the specific type, that could be:

Point LineString Polygon MultiPoint MultiLineString MultiPolygon GeometryCollection

Each one of them has its own implementation, take a look at GeoJSON Objects

Some implementations of that:

type Point struct {
    Type        string `json:"type"`
    Coordinates []float64  `json:"coordinates"`
}

type LineStringAndMultipoint struct {
    Type        string  `json:"type"`
    Coordinates [][]float64`json:"coordinates"`
}

type Polygon struct {
    Type        string    `json:"type"`
    Coordinates [][][]float64 `json:"coordinates"`
}

// Alternatively you could create a all-in-one struct using interface as Coordinates

type GeoJSON struct {
    Type        string    `json:"type"`
    Coordinates interface {}`json:"coordinates"`
}

Some example using it:

(Example)[https://gist.github.com/Lebski/8f9b5992fec0bf175285f1c13b1e5051]

insertResult, err := PointCollection.InsertOne(context.TODO(), GeoJSON{Type: "Point", []float64{lat, long}})
    if err != nil {
        log.Fatal("Could not insert new Point")
    }
    log.Infof("Inserted new Point. Id: %s\n", insertResult.InsertedID)