Hi folks,
I've created a basic CRUD application using gin and Mongodb (mgo). I can't figure out how to create a subdocument.
For example, if I had:
type Article struct {
Title string `form:"title" json:"title"`
Body string `form:"body" json:"body"`
Categories []*Category
}
How would I find an article and then insert a category?
Any help much appreciated!
评论:
koalefant:
ewanvalentine:Haven't tested it so no guarantees, but I assume something like the following:
type Article struct { Title string `bson:"title" json:"title"` Body string `bson:"body" json:"body"` Categories []*Category `bson:"categories" json:"categories"` } cat := &Category{} change := mgo.Change{ Update: bson.M{"$push": bson.M{"categories": cat}}, } c := session.DB(database).C(collection) _, err := c.Find(bson.M{"title": "cats in hats et al"}).Apply(change, nil) if err := nil { panic("not enough cats in hats") }
hjkelly87:Spot on! Thank you so much!
I'm assuming you have already created the documents themselves, and you're only struggling with adding additional categories. If that's not the case, and you're not sure how to insert a document with subdocuments all at once, let me know.
I prefer to do this as one query rather than separately finding an object and then having to update the whole thing (when really you're just appending to an array).
selector := bson.M{"title": titleYouWant} changes := bson.M{"$push": bson.M{"categories": Category{"My Category"}}} changeInfo, err := session.DB(database).C(collection).Update(selector, changes) if err != nil { // handle error gracefully } else { // oh hai it worked fmt.Println(changeInfo) }
A few thoughts:
- The lowercase "categories" attribute name came from the mgo.v2/bson docs which explain that it uses the lowercase version of the struct attribute if no
bson:actualFieldName
is given via golang's struct tags. - My structs always have an ID field, which makes the more foolproof/predictable to find:
type Article struct {
Id bson.ObjectId `bson:"_id"`
...
}
*edit: I suck at reddit formatting
