1

I want to select a subdocument using mgo. Before select, the query should query the right top level document. I tried this:

name := "anything"
w := models.Wallet{}
c := s.DB("ep2").C("users")
err := c.Find(bson.M{"name": name}).Select(bson.M{"wallet": 1}).One(&w)

These are the structs:

type User struct {
    Id     bson.ObjectId `bson:"_id,omitempty" json:"-" form:"-"`
    Wallet Wallet        `bson:"wallet,omitempty" json:"wallet,omitempty" form:"wallet,omitempty"`
} 

type Wallet struct {
    Taddr     string  `json:"taddr,omitempty" form:"taddr,omitempty"`
    TaddrPriv string  `json:"-" form:"-"`
    Tbalance  float64 `json:"tbalance" form:"tbalance,omitempty"`
}

It returns an empty wallet document.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
nayD93
  • 13
  • 2

1 Answers1

0

With Query.Select() you may specify which fields of the queried document(s) you want to retrieve, but the retrieved entities will not be the values of the selected fields, they will still be the values of the queried documents!

So since you are querying the "users" collection, you should pass a value of *User to Query.One():

name := "anything"
u := models.User{}
c := s.DB("ep2").C("users")
err := c.Find(bson.M{"name": name}).Select(bson.M{"wallet": 1}).One(&u)
if err != nil {
    // Handle error
    return
}

// Wallet is in u.Wallet
fmt.Printf("Result wallet: %+v", u.Wallet)
icza
  • 389,944
  • 63
  • 907
  • 827
  • Thank you very much. Is there any way to only receive wallet? Maybe sth. like add wallet collection and set a foreign key to User? – nayD93 Jun 16 '17 at 08:01
  • @nayD93 The query above only retrieves the wallet wrapped in a user (plus the user id). If even this bothers you, you may use the [aggregation framework](https://docs.mongodb.com/manual/aggregation/) where it's possible to project the returned data, and then you could retrieve only the wallet, unwrapped, without the user id. See [`Collection.Pipe()`](https://godoc.org/gopkg.in/mgo.v2#Collection.Pipe) as a starting point. – icza Jun 16 '17 at 08:23
  • @nayD93 And of course splitting wallet into its own collection and querying that is also a viable option. – icza Jun 16 '17 at 09:33