Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to Decode the ObjectId SubValue from MongoDB results in Golang

Tags:

mongodb

go

I am using the MongoDb Go Driver and I am unable to get the ObjectId subvalue from the JSON decoded in my structs.

Note: I am using a different library/API than this question, so please don't mark this as duplicate.

import (
    "net/http"
    "github.com/go-chi/chi"
    "encoding/json"
    "time"
    "context"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "fmt"
)

I have a type of struct like this for processing the results

type Contact struct {
    Id  struct {
        ObjId   string  `json:"$oid"`
    } `json:"_id"`
    Name    string `json:"name"`
    Email   string `json:"email"`
    Health  struct {
        Weight  int `json:"weight"`
        Height  int `json:"height"`
    } `json:"health"`    
}

And then I go to retrieve the contacts like this:

var contacts []Contact
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
    panic(err)
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
    var contact Contact
    fmt.Println(cursor)
    cursor.Decode(&contact)
    contacts = append(contacts, contact)
}
if err := cursor.Err(); err != nil {
    panic(err)
}
// I want to do more with the contacts, but .Id is empty :-(
fmt.Println(contacts)

The subfields for "health" appear exactly as they should, but for some reason the subfield from the "_id" part of the results is nowhere to be found. Can anyone help me with this??

The JSON response from the database comes out like this, and for some reason I am able to get the subfields for the health field, but not the _id field. Why not?

Raw JSON response of DB

[{
    "_id": { 
        "$obj": "5c601648ae25e40e2631c3ef" 
    }, 
    "name": "Bob Smith", 
    "email": "[email protected]", 
    "health": { 
        "height": 192, 
        "weight": 85 
    }
}]

fmt.Println's output of the decoded contacts array:

[{{} Bob Smith [email protected] {192 85}}]
like image 273
Adam D Avatar asked Dec 03 '22 18:12

Adam D


1 Answers

Thanks to this excellent tutorial and this anwser I was able to find the answer.

I needed to set the ID in my struct as a primitive.ObjectID, and made sure I had imported "go.mongodb.org/mongo-driver/bson/primitive"

type Contact struct {
    ID      primitive.ObjectID  `json:"_id" bson:"_id"
    Name    string `json:"name" bson:"name"`
    Email   string `json:"email" bson:"email"`
    Health  struct {
        Weight  int `json:"weight" bson:"weight"`
        Height  int `json:"height" bson:"height"`
    } `json:"health" bson:"health"`    
}

For those looking to use the official MongoDB Go driver, see this tutorial below provides very good explanation and examples of how to do all the CRUD operations necessary for a basic REST api etc.

Using the official MongoDB Go driver

like image 94
Adam D Avatar answered Jan 21 '23 10:01

Adam D