Reputation: 514
I am trying to fetch some data from mongo
in go
and using gopkg.in/mgo.v2
. I have a nested data in mongo.
Note: This is an old database I cannot change structure for and just want to query the data.
I have a database with fields id
, name
and details
. and I have to get details based on id
My code:
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Person struct {
Name string
Id string
Details string
}
func main() {
session, err := mgo.Dial("mongodb://localhost:27017/naren")
c := session.DB("naren").C("people")
result := Person{}
err = c.Find(bson.M{"id": "12345"}).One(&result)
if err != nil {
fmt.Println(err)
}
fmt.Println("Details:", result.Details)
fmt.Println("Name:", result.Name)
fmt.Println("Id:", result.Id)
}
Id
and Name
are printing fine but result.Details
prints an empty string even when there is data. I just want to print json as string or am happy with a json data.
I have also tried
...
type Person struct {
...
Details string `json:"details"`
}
But still get empty string. Thanks in advance.
Upvotes: 2
Views: 3965
Reputation: 376
In my case, the field is an embedded document (maybe a JSON object or a JSON array). I have to set the field type to bson.RawValue
:
type Person struct {
Name string
Id string
Details bson.RawValue
}
and then check whether Details is an object or an array using if-else:
var d interface{}
var m bson.M
var a bson.A
e := person.Details.Unmarshal(&m)
d = m
if e != nil {
_ = person.Details.Unmarshal(&a)
d = a
}
After unmarshal, d
will be a bson.M
or bson.A
.
Side note: bson.M{}
objects will default be decoded to {Key: realKey, Value: realValue}
, if you want {realKey: realValue}
structure, unmarshal with a custom registry:
rb := bson.NewRegistryBuilder()
rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.M{}))
reg := rb.Build()
var d interface{}
var m bson.M
var a bson.A
e := object.Data.UnmarshalWithRegistry(reg, &m)
d = m
if e != nil {
_ = object.Data.UnmarshalWithRegistry(reg, &a)
d = a
}
Upvotes: 0
Reputation: 514
I am very new to go. This seems very basic now. The value of key details
was JSON
The fix was that I changed the type of details to bson.M
from
type Person struct {
Name string
Id string
Details string
}
to
type Person struct {
Name string
Id string
Details bson.M
}
now I can access the details like
res, err := json.Marshal(result.Details)
fmt.Println(string(res))
Thanks @putu for pointing me to the right direction.
Upvotes: 5