Inserting arrays of Object IDs in mgo - mongodb

So recently I've been trying to insert different types of data into structures using mgo, and I've ran into a bit of a snag. When trying to insert an array of object IDs, I can't seem to figure out that format if I were to populate that object ID array within the structure.
Here's the structure as follows
type Group struct {
ID bson.ObjectId `json:"id" bson:"_id"`
GroupName string `json:"groupName"`
UserIDs []*bson.ObjectId `json:"users" bson:"userid"`
Expected []*int `json:"expected"`
Actual []*int `json:"actual"`
}
And the operation I am trying to run is to insert a new "test" table with a single userID into UserIDs.
array := []*bson.ObjectId{&findJ.ID}
c = Session.DB("test").C("Group")
err = c.Insert(&Group{GroupName: "test", UserIDs: array})
ThisPanic(err)
Where findJ has it's own ID from a separate structure. What am I doing wrong here, as it is causing a panic on inserting the array.

Related

GORM unable to update data in one to many relationship

I have two tables users and documents. They are related in such a way that each document must belong to a user using a one to many relationship. When I try updating a document I get the following error
ERROR: insert or update on table "documents" violates foreign key
constraint "fk_users_documents" (SQLSTATE 23503)
Here are my structs definition and update function
type User struct {
gorm.Model
Name string
Email string
Password string
Documents []Document
}
type Document struct {
gorm.Model
Name string
UserID uint
}
//Update document by id
func (h handler)UpdateDocument(w http.ResponseWriter, r *http.Request) {
// once again, we will need to parse the path parameters
var updatedDoc Document
reqBody, _ := ioutil.ReadAll(r.Body)
json.Unmarshal(reqBody, &updatedDoc)
var document Document
vars := mux.Vars(r)
id := vars["id"]
if result := Db.First(&updatedDoc, id); result.Error != nil {
fmt.Println(result.Error)
}
document.Name=updatedDoc.Name
Db.Save(&document)
json.NewEncoder(w).Encode(&updatedDoc)
}
You are calling Db.Save(&document) but document has only its Name field populated. This means that the UserID is set to 0. I'm guessing you don't have any user with ID 0 present in the User table, therefore this violates the foreign key constraint.
The UserID field shall always be set to an existing user when updating a document otherwise the query will fail.
Regardless of this, I'd suggest you to study a bit of database and golang basics because the code you posted is quite messy.

Gorm Model structure failing to bind values when using postgres function call

I have a structure called "Friend"
type Friend struct {
gorm.Model
Name string,
Address string,
etc
I have a postgres function that returns all friends for a zipcode.
var friends []types.Friend
db.Raw("select findByZip(?)", zipCode).Scan(&friends)
The array of friends contains the correct number of records returned from the query findByZip(?)
When I iterate over the array the values for Friend are not present.
for _, friend := range friends {
fmt.Println(friend.Name)
fmt.Println(friend.Address)
fmt.Println("--------------------")
}
I am unable to get the values from the stored proc call to bind to the correct fields in the structure.
Open to any suggestions

How to write nested bson.M{} correctly

Suppose we have the following struct:
type shop struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Brands *brand `json:"brand,omitempty" bson:"brand,omitempty"`
}
type brand struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"deploymentid,omitempty"`
}
I tried to find a document using findOne() but I don't get any document even there is a result match by using the MongoDB shell.
filter := bson.M{"brand" : bson.M{"_id" : someValue}}
var shopWithBrand shop
mycollection.findOne(ctx , filter).Decode(&shopWithBrand)
What mistake did I make?
This filter:
filter := bson.M{"brand" : bson.M{"_id" : someValue}}
Tells you want documents that have a brand field that is an embedded document having a single _id field whose value is the value of someValue.
This would actually work if your embedded documents would only consist of this single _id field, but your embedded brand has this ID field mapped to deploymentid and most likely has other fields as well (which you "stripped off" to minimize the example), and that is why it won't match.
Instead you want documents that have a brand field being a document that has a matching deployment field among other fields. This is how you can express that:
filter := bson.M{"brand.deploymentid" : someValue}

f# Insert on MongoDB using Records

I've been trying for a while to insert on MongoDB using only records with no success.
My problem is that I want to create a simple insert function which I send a generic type and it is inserted into the database.
Like so.
let insert (value: 'a) =
let collection = MongoClient().GetDatabase("db").GetCollection<'a> "col"
collection.InsertOne value
From this function, I tried inserting the following records.
// Error that it can't set the Id
type t1 = {
Id: ObjectId
Text: string
}
// Creates the record perfectly but doesn't generate a new Id
type t2 = {
Id: string
Text: string
}
// Creates the record and autogenerates the Id but doesn't insert the Text, and there are two Ids (_id, Id#)
type t3 = {
mutable Id: ObjectId
Text: string
}
// Creates the record and autogenerates the Id but for every property it generates two on MongoDB (_id, Id#, Text, Text#)
type t4 = {
mutable Id: ObjectId
mutable Text: string
}
So does anyone can think of a solution for this or am I stuck having to use a class.
// Works!!!
type t5() =
member val Id = ObjectId.Empty with get, set
member val Name = "" with get, set
Also, does anyone has any Idea of why when the C# MongoDB library translates the mutable he gets the property with the # at the end?
I would be fine with having all my properties set as mutable, although this wouldn't be my first choice, having he create multiple properties on the DB is quite bad.
You could try annotating your records with CLIMutable (and no mutable fields).
The #s end up in the DB because MongoDB using reflection and F# implementing mutable with backing fields fieldName#

Nested documents in model struct

Say I have a UserModel like so:
type (
OrderModel struct {
ID bson.ObjectId `json:"id" bson:"_id"`
...
}
UserModel struct {
...
// What do I store here? Is this an array of strings? An array of bson.ObjectID? Or an Array of OrderModel?
Orders []string `json:"orders" bson:"orders"`
Orders []bson.ObjectId `json:"orders" bson:"orders"`
Orders []OrderModel `json:"orders" bson:"orders"`
...
}
)
func (user *UserModel) PopulateOrders() {
orders := []OrderModel{}
// Query orders and assign to variable orders to then be assigned the the user Object
// {magic query here}
user.Orders = orders
}
In MongoDB, an array of ObjectIDs would be stored to reference the OrderModel documents. Later on, I have a function that will populate the Order documents like described above: PopulateOrders.
What is the best way for the case above?
I would use 2 separate fields, one for the slice of IDs, and one for the slice of lazily loaded objects.
Omit the lazily loaded object slice from saving. It could look like this:
type UserModel struct {
// ...
OrderIDs []bson.ObjectId `json:"orderIDs" bson:"orderIDs"`
Orders []OrderModel `json:"orders" bson:"-"`
// ...
}
Note that I intentionally did not exclude Orders from JSON serialization, as it is (may) be useful in JSON representation.