15

I am new to mongodb-go-driver. But i am stuck.

cursor, e := collection.Find(context.Background(), bson.NewDocument(bson.EC.String("name", id)))

for cursor.Next(context.Background()) {

    e := bson.NewDocument()
    cursor.Decode(e)

    b, _ := e.MarshalBSON()
    err := bson.Unmarshal(b, m[id])
}

When look at the contents of m[id], it has no content - all nulls.

My map is like this : m map[string]Language

and Language is defined like :

type Language struct {
    ID         string   `json:"id" bson:"_id"`                   // is this wrong?
    Name       string   `json:"name" bson:"name"`
    Vowels     []string `json:"vowels" bson:"vowels"`
    Consonants []string `json:"consonants" bson:"consonants"`
}

What am I doing wrong?

I am learning using this example : https://github.com/mongodb/mongo-go-driver/blob/master/examples/documentation_examples/examples.go

iam thadiyan
  • 471
  • 1
  • 4
  • 19

4 Answers4

23

Newer "github.com/mongodb/mongo-go-driver" expects object IDs defined as

type Application struct {
    ID      *primitive.ObjectID `json:"ID" bson:"_id,omitempty"`
}

This serializes into JSON "ID":"5c362f3fa2533bad3b6cf6f0" and here is how you get the ID from insert result

if oid, ok := res.InsertedID.(primitive.ObjectID); ok {
    app.ID = &oid
}

Convert from string

appID := "5c362f3fa2533bad3b6cf6f0"    
id, err := primitive.ObjectIDFromHex(appID)
if err != nil {
    return err
}
_, err = collection.DeleteOne(nil, bson.M{"_id": id})

Convert into string

str_id := objId.Hex()
Alexey Podlasov
  • 993
  • 10
  • 18
12

The official MongoDB driver uses the objectid.ObjectID type for MongoDB ObjectIds. This type is:

type ObjectID [12]byte

So you need to change your struct to:

type Language struct {
    ID         objectid.ObjectID   `json:"id" bson:"_id"`             
    Name       string   `json:"name" bson:"name"`
    Vowels     []string `json:"vowels" bson:"vowels"`
    Consonants []string `json:"consonants" bson:"consonants"`
}

I had success with:

m := make(map[string]Language)
cursor, e := collection.Find(context.Background(), bson.NewDocument(bson.EC.String("name", id)))

for cursor.Next(context.Background()) {

    l := Language{}
    err := cursor.Decode(&l)
    if err != nil {
        //handle err
    }
    m[id] = l // you need to handle this in a for loop or something... I'm assuming there is only one result per id
}
Farhad Farahi
  • 35,528
  • 7
  • 73
  • 70
  • may I ask, do you really need the _id checked out from Mongodb? – tomriddle_1234 Aug 27 '18 at 01:43
  • I notice that this struct describes both JSON and BSON serialisation. This feels like the same struct that is 'fetched' from the database is then presented to the user as JSON without transformation, essentially exposing your data structures directly to the client. As a relative newcomer to Go, I am genuinely very curious as to whether this is really considered good practice? Is this idiomatic go? – apostrophedottilde Feb 16 '19 at 10:10
  • I will leave the "is this idiomatic go?", to the experts to answer. You can always use `Field int json:"-"` to avoid sending a field to client – Farhad Farahi Feb 16 '19 at 11:05
8

Update: New changes were made recently, now have to change to:

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

type Language struct {
    ID         primitive.ObjectID `bson:"_id,omitempty"` // omitempty to protect against zeroed _id insertion         
    Name       string   `json:"name" bson:"name"`
    Vowels     []string `json:"vowels" bson:"vowels"`
    Consonants []string `json:"consonants" bson:"consonants"`
}

And take the ID value:

log.Println("lang id:", objLang.ID)
...
Illia Danko
  • 555
  • 4
  • 10
2

I was getting

cannot decode objectID into an array

so i changed to

ID interface{} `bson:"_id,omitempty"`

without any issues

Yianni
  • 69
  • 2