13

I have a fairly odd question that I have been trying to wrap my head around and am looking of some pointers as to the best approach. I am use mgo to filter a collection that contains a few different types of structs and am trying to cast from bson.M to the proper struct after the fact. Basically I'd like to be able to filter the collection and look at each result and based on a common field cast to the proper struct.

Here is sample of the structs I am trying to use.

  type Action interface {
    MyFunc() bool
  }

  type Struct1 struct {
    Id bson.ObjectId `bson:"_id,omitempty"`
    Type  string `bson:"type"`
    Struct1Only string `bson:"struct1only"`
  }

  func (s Struct1) MyFunc() bool {
    return true
  }

  type Struct2 struct {
    Id bson.ObjectId `bson:"_id,omitempty"`
    Type string `bson:"type"`
    Struct2Only string `bson:"struct2only"`
  }

  func (s Struct2) MyFunc() bool {
    return true
  }

My initial idea was to do something like:

var result bson.M{}
err := c.Find(bson.M{nil}).One(&result)

Then switch on the type field and cast to the proper struct, but honestly I am new to go and mongo and am sure there is better way to do this. Any suggestions? Thanks

3
  • You're storing two different struct types into one collection? I'm not aware of any way to guess the right one to cast the result to without explicitly switching on the presence of the fields that are specific to either struct. Commented Apr 1, 2016 at 18:10
  • Furthermore, it is to say that you could and probably should combine the two structs if they are just different in one field. A non-existing field simply evaluates to nil. Commented Apr 2, 2016 at 0:45
  • I have simplified the structs for the example, in my project there are about 10 fields that are different between them, they actually share about 15 fields. I could combine the structs and just have a few fields that will be nil depending on the type, I was just looking to keep the structs separate as I think it would be cleaner. Commented Apr 2, 2016 at 5:38

1 Answer 1

31

You don't have to convert bson.M to struct, instead, you directly pass a struct pointer to the One function

var struct2 Struct2
err := c.Find(bson.M{nil}).One(&struct2)

In case of you still want to convert bson.M to struct, use Marshal and Unmarshal

var m bson.M
var s Struct1

// convert m to s
bsonBytes, _ := bson.Marshal(m)
bson.Unmarshal(bsonBytes, &s)
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.