Riaru Neimu
Riaru Neimu

Reputation: 53

Inserting Dates Into Mongo with Golang

I am trying to create a Golang MongoDB connector that takes in a request from a client and updates/inserts the request body into a database. An example of the request body is:

    {
        "_id": {
            "$oid": <hexOID>
        },
        "DateCreated": {
            "$date": 1460091636474
        },
        "DateModified": {
            "$date": 1542241349721
        }
    }

The current Mongo driver and BSON library I am using is the one located at github.com/globalsign/mgo/ and github.com/globalsign/mgo/bson respectively.

Whenever I try to unmarshal the above response, I get an error:

cannot parse date: "{\r\n        \"$date\": 1460091636474\r\n    }"

I've read around and saw some answers about creating a custom marshaller/unmarshaller but how would I go about doing that if it does solve this problem?

A subset of my code is as follows:

var update interface{}
errUpdate := bson.UnmarshalJSON(body, &update)
if errUpdate != nil {
    fmt.Println(errUpdate)
}
dbErr = collection.Update(query, update)

I keep update as an interface since the request body that is passed constantly changes and is not well-defined.

Upvotes: 0

Views: 3769

Answers (1)

Wan B.
Wan B.

Reputation: 18835

First of all, the format of JSON in your example is called MongoDB Extended JSON. This is important, as you need to follow the format for extended JSON date. It's either $date with ISO-8601 string, or $date with $numberLong with Unix Epoch.

Another note is with Update you need an update operation i.e. $set. If you're intending to replace the document, use Replace. Although replacing _id doesn't quite make sense, the example below will use Replace as assumed from the example.

Given an example document in database as below:

db.collection.insert({
              "_id": ObjectId("5bf36072a5820f6e28a4736c"),
              "Foo":1
})

An alternative to using globalsign/mgo is to use mongo-go-driver/bson package, there's a method UnmarshalExtJSON() that you could easily utilise to parse extended JSON.

Using the current version (0.0.18), an example would be:

import (
    "github.com/mongodb/mongo-go-driver/bson"
    "github.com/mongodb/mongo-go-driver/mongo"
)

replacement := bson.D{}
// Example of response body
data := `{"_id":{"$oid":"5bf36072a5820f6e28a4736c"},"DateModified":{"$date":{"$numberLong":"1542241349721"}},"DateCreated":{"$date":{"$numberLong":"1460091636474"}}}`

err = bson.UnmarshalExtJSON([]byte(data), true, &replacement)
if err != nil {
    log.Fatal(err)
}
query := bson.D{{"Foo", 1}}
replaceResult, err := c.ReplaceOne(context.Background(), query, replacement)

Upvotes: 1

Related Questions