4

I'm trying to learn Go API development. I have a MongoDB instance running in a Docker container. I'm trying to follow a few guides but am failing on simple queries. I don't fully understand the use of BSON and JSON tags here. I do know what those terms mean. So here is my code.

import (
    "fmt"
    "time"

    "gopkg.in/mgo.v2/bson"
)

const (
    hosts      = "localhost:27017"
    database   = "my_database"
    username   = "dev1"
    password   = "password123"
    collection = "users"
)

type users struct {
    user string `bson:"user" json:"user"`
    data string
}

func main() {

    fmt.Println("Starting Application!")

    info := &mgo.DialInfo{
        Addrs:    []string{hosts},
        Timeout:  60 * time.Second,
        Database: database,
        Username: username,
        Password: password,
    }

    session, err1 := mgo.DialWithInfo(info)
    if err1 != nil {
        panic(err1)
    }
    defer session.Close()

    col := session.DB(database).C(collection)

    var user users
    var books []users
    var username = "cat"

    col.Insert(&users{user: "dog", data: "blah"})
    err3 := col.Find(bson.M{"user": username}).One(&user)
    fmt.Println(user)
    fmt.Println(err3)
    count, err2 := col.Count()
    if err2 != nil {
        panic(err2)
    }
    fmt.Println(fmt.Sprintf("Messages count: %d", count))

    fmt.Println(user)
    col.Find(bson.M{}).All(&books)
    fmt.Println(books)
}

Basically I'm getting empty objects on the print line but am getting the correct Message count. I inserted the objects with robomongo if that helps.

Objects in Collection

wasmup
  • 14,541
  • 6
  • 42
  • 58
camccar
  • 690
  • 12
  • 24
  • How could you find `"cat"` when you only inserted `"dog"`? I mean it "might" be there already, but as a self contained example your code seems to contradict itself and is looking for something different than you actually insert. So if you are writing to the correct source, then where is `"dog"`? Should this not indicate that you are actually writing to somewhere different? – Neil Lunn Aug 04 '17 at 13:55
  • Good question. I already have cat inserted. I tried inserting dog and then reading all to see if mgo inserts differently than robomongo. But the dog didn't even get inserted. Check out the picture I attached. – camccar Aug 04 '17 at 14:00

1 Answers1

9

You must export fields of structs, else they are ignored by the mgo package. Change fields of users to User and Data.

type users struct {
    User string `bson:"user" json:"user"`
    Data string `bson:"data" json:"data"` 
}

By default when a struct value is transformed / stored / retrieved from MongoDB, the field name is used. If you want to use different names, you may use tags to tell what names should the fields map to.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Thanks I'll check this when I get home tonight – camccar Aug 04 '17 at 14:19
  • Also, can you explain what is doing the exporting? I've done a lot of node and with node you just type export. is it the bson and json tags here what makes it exported? – camccar Aug 04 '17 at 14:40
  • 2
    @camccar Identifiers that start with capital letter are exported, it means they are accessible from all packages. Identifiers that do not start with capital letters are not exported, and are only accessible from the declaring package. – icza Aug 04 '17 at 14:43
  • Good tips! thanks, I have same problem . I wonder if there is a way to make mgo automatically use the fields of a struct , no matter a field is capital or not. – Mithril Jan 10 '18 at 09:11
  • @Mithril Fields must be exported, else the `mgo` package would not have access to them. This is a language restriction, not `mgo`'s restriction. – icza Jan 10 '18 at 09:12