Inserting struct in mongodb in Golang - mongodb

I am trying to insert a struct in mongo database.
type SecretsStruct struct {
UserID string `bson:"userid" json:"userid"`
secretOne string `bson:"secret_one" json:secret_one`
secretTwo string `bson:"secret_two" json:secret_two`
secretThree string `bson:"secret_three" json:secret_three`
}
func (c *SecretsStruct) SetSecrets(userId string, encryptedKeys
[][]byte){
c.UserID = userId
c.secretOne = hex.EncodeToString(encryptedKeys[0])
c.secretTwo = hex.EncodeToString(encryptedKeys[1])
c.secretThree = hex.EncodeToString(encryptedKeys[2])
log.Printf("This is the c %s", c)
}
g := SecretsStruct{}
g.SetSecrets(userStruct.UserID, encryptedKeys)
err = secretCollection.Insert(g)
if err != nil {
panic(err)
}
I have tried inserting the byte arrays corresponding to the secrets but of no help. The result which gets populated to the corresponding insertion operation is :
{'_id': ObjectId('5b80117c118c660aaa0c87c2'),
'userid': 'eb19d220-ef13-43aa-8a7f-f78637718000'}
On the other hand, if I try to insert same data with a map but without struct.
secretCollection.Insert(bson.M{"userid": userStruct.UserID,
"secret_one": encryptedKeys[0],
"secret_two": encryptedKeys[1],
"secret_three": encryptedKeys[2]})
The insertion operation executes successfully.

You have to export your struct fields, so that another package (in this case mgo) can access them:
type SecretsStruct struct {
UserID string `bson:"userid" json:"userid"`
SecretOne string `bson:"secret_one" json:secret_one`
SecretTwo string `bson:"secret_two" json:secret_two`
SecretThree string `bson:"secret_three" json:secret_three`
}

Related

Create nested struct based on url query parameters

My goal is to get some filtered records from database. Filtration is based on a struct which depends on another struct:
type Group struct {
ID primitive.ObjectID
Name string
}
type Role struct {
ID primitive.ObjectID
Name string
Description string
Groups []*group.Group
}
I create an object of Role struct from URL query parameters:
var roleWP Role
if r.URL.Query().Has("name") {
name := r.URL.Query().Get("name")
roleWP.Name = name
}
if r.URL.Query().Has("description") {
description := r.URL.Query().Get("description")
roleWP.Description = description
}
if r.URL.Query().Has("groups") {
//How would look groups parameter?
}
Filling name and description fields of Role struct is pretty simple. The whole url would be: myhost/roles?name=rolename&description=roledescription
But how would look url if I want to pass data for Group struct? Is it possible to pass data as a json object in query parameter? Also, I want to mention that groups field in Role is an array. My ideal dummy url would look like: myhost/roles?name=rolename&description=roledescription&groups={name:groupname1}&groups={name:groupname2}
Loop through the groups, split on :, create group and append to slice:
roleWP := Role{
Name: r.FormValue("name"),
Description: r.FormValue("description"),
}
for _, g := range r.Form["groups"] {
g = strings.TrimPrefix(g, "{")
g = strings.TrimSuffix(g, "}")
i := strings.Index(g, ":")
if i < 0 {
// handle error
}
roleWP.Groups = append(roleWP.Groups, &Group{g[:i], g[i+1:]})
}
Here's how to use JSON instead of OP's ideal format:
roleWP := Role{
Name: r.FormValue("name"),
Description: r.FormValue("description"),
}
for _, s := range r.Form["groups"] {
var g Group
err := json.Unmarshal([]byte(s), &v)
if err != nil {
// handle error
}
roleWP.Groups = append(roleWP.Groups, &g)
}

Convert a string slice to a BSON array

I am trying to insert an array into a MongoDB instance using Go. I have the [] string slice in Go and want to convert it into a BSON array to pass it to the DB using the github.com/mongodb/mongo-go-driver driver.
var result bson.Array
for _, data := range myData {
value := bson.VC.String(data)
result.Append(value)
}
This loops over each element of my input data and tries to append it to the BSON array. However the line with the Append() fails with panic: document is nil. How should I do this conversion?
Edit: The code in the question and this answer is no longer relevant because the bson.Array type was deleted from the package. At the time of this edit, the bson.A and basic slice operations should be used to construct arrays.
Use the factory function NewArray to create the array:
result := bson.NewArray()
for _, data := range myData {
value := bson.VC.String(data)
result.Append(value)
}
As mentioned by #Cerise bson.Array has since been deleted. I do this with multiple utility functions as follows:
func BSONStringA(sa []string) (result bson.A) {
result = bson.A{}
for_, e := range sa {
result = append(result, e)
}
return
}
func BSONIntA(ia []string) (result bson.A) {
// ...
}
Converting a slice of string (ids) to BSON array
var objIds bson.A
for _, val := range ids {
objIds = append(objIds, val)
}
log.Println(objIds)

mgo golang doesnt update empty array using $set

struct and method:
type Group struct {
Id int64 `bson:"_id,omitempty"`
MediaFilterExceptionUserIds []int `bson:"media_filter_exception_user_ids,omitempty"`
}
func (g *Group) Save() error {
return DB.C("groups").UpdateId(g.Id, bson.M{"$set": &g})
}
func (g *Group) FindById() error {
return DB.C("groups").FindId(g.Id).One(&g)
}
trying to set media_filter_exception_user_ids to an empty []int{} and it doesn't work:
group := Group{}
group.FindById(123)
group.MediaFilterExceptionUserIds = []int{}
group.Save()
It works when there's an item inside the slice, but empty slice is not set.
MediaFilterExceptionUserIds type should change from []int to *[]int,
type Group struct {
Id int64 `bson:"_id,omitempty"`
MediaFilterExceptionUserIds *[]int `bson:"media_filter_exception_user_ids,omitempty"`
}
and then
group.MediaFilterExceptionUserIds = &[]int{}
will set it to an empty array in mongodb

Cannot save structure into mongodb with golang (only empty records created)

I have the following structure
type Result struct {
nid string
timestamp int64
hexhash string
addr string
}
which I want to save into mongodb:
I create it
r := Result{hex_id, int64(msg.timestamp.Unix()), hexhash, msg.addr.String()}
And test if it is created correctly:
fmt.Println(r)
Which gives me result I'm expecting:
{b8da3f19d1318af6879976c1eea66c78c48e1144 1421417252
65072917F19D7F4C4B54C9C66A3EB31F77012981 127.0.0.1:65290}
Then I save it into mongo:
h.c.Insert(r)
But in mongo i see only empty records:
db.data.find()
{ "_id" : ObjectId("54b91a268da6c829a412cd4d") }
The h in the code above defined as
type Handler struct {
storage map[string]Message
new_msg chan Message
new_inp chan Input
c *mgo.Collection
}
and
h.c = session.DB(DATABASE).C(COLLECTION)
The fileds of your record need to be public for other packages (like the MongoDB wrapper) to see them. Rename the fields like this:
type Result struct {
Nid string
Timestamp int64
Hexhash string
Addr string
}

MGO - empty results returned from Mongo that has results

I have a GOLANG struct as follows:
type OrgWhoAmI struct {
FriendlyName string `json:"friendlyName"`
RedemptionCode string `json:"redemptionCode"`
StartUrls []StartUrl `json:"startUrls"`
Status string `json:"status"`
Children []OrgChildren `json:"childrenReemptionCodes"`
}
type StartUrl struct {
DisplayName string `json:"displayName"`
URL string `json:"url"`
}
type OrgChildren struct {
FriendlyName string `json:"childFriendlyName"`
RedemptionCode string `json:"childRedemptionCode"`
}
I've created and successfully inserted records into a MongoDB collection (as I can see the results by querying Mongo with the CLI mongo program) - but when I query with MGO as follows, I get nothing:
func main() {
session, sessionErr := mgo.Dial("localhost")
defer session.Close()
// Query All
collection := session.DB("OrgData").C("orgWhoAmI")
var results []OrgWhoAmI
err = collection.Find(bson.M{}).All(&results)
if err != nil {
panic(err)
}
for _, res := range results {
fmt.Printf("Result: %s|%s\n", res.FriendlyName, res.RedemptionCode)
}
}
The results printed are:
Result: |
Result: |
Result: |
Result: |
If I ask for the count for records, I get the correct number, but all values for all fields are blank. Not sure what I'm missing here.
If you aren't creating them in go, it's probably not serializing the key names for you properly. The default for bson is to lowercase the keys, so you need to specify it if you want something else. Also note that you have a typo in OrgWhoAmI for json:"childrenReemptionCodes" (should be Redemption, I'm guessing). You can specify both bson and json separately if you want them to be different.
type OrgWhoAmI struct {
FriendlyName string `bson:"friendlyName" json:"friendlyName"`
RedemptionCode string `bson:"redemptionCode" json:"redemptionCode"`
StartUrls []StartUrl `bson:"startUrls" json:"startUrls"`
Status string `bson:"status" json:"status"`
Children []OrgChildren `bson:"childrenRedemptionCodes" json:"childrenRedemptionCodes"`
}
type StartUrl struct {
DisplayName string `bson:"displayName" json:"displayName"`
URL string `bson:"url" json:"url"`
}
type OrgChildren struct {
FriendlyName string `bson:"childFriendlyName" json:"childFriendlyName"`
RedemptionCode string `bson:"childRedemptionCode" json:"childRedemptionCode"`
}