Interface Types as Models in mgo (Go)
Problem:
In a scenario involving workflows and embedded nodes of various types, using an interface for modeling nodes in MongoDB with mgo results in an error. The error occurs because mgo cannot unmarshal the embedded Node documents without type information.
Solution:
To overcome this limitation, consider defining a struct to hold both the Node type and the associated type information:
<code class="go">type NodeWithType struct { Node Node `bson:"-"` Type string }</code>
Within the Workflow struct, use an array of NodeWithType structs to store the nodes:
<code class="go">type Workflow struct { CreatedAt time.Time StartedAt time.Time CreatedBy string Nodes []NodeWithType }</code>
To decode the data correctly, implement the SetBSON function on NodeWithType:
<code class="go">func (nt *NodeWithType) SetBSON(r bson.Raw) error { // Decode the type string typeStr := r.String() // Create a new Node value based on the type string switch typeStr { case "EmailNode": nt.Node = &EmailNode{} case "TwitterNode": nt.Node = &TwitterNode{} default: return errors.New("Unknown node type") } // Unmarshal the remaining data to the Node value bsonBytes, err := bson.Marshal(r.Body) if err != nil { return err } return bson.Unmarshal(bsonBytes, nt.Node) }</code>
This approach allows mgo to unmarshal the embedded nodes correctly, based on the type information stored in the NodeWithType struct.
The above is the detailed content of How to Model Embedded Nodes of Different Types in MongoDB with mgo using Interfaces?. For more information, please follow other related articles on the PHP Chinese website!