Have a struct as follows
type Person struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string `json:"name"`
Phone string `json:"phone"`
}
and then want to nest it in another struct
type Customer struct {
ID bson.ObjectId `bson:"_id,omitempty"`
StoreName string
Person Person `json:"persons"`
}
instantiated as
customer := Customer{bson.NewObjectId(), "Seattle", p1}
and insterted into Mongo db (I am using the mgo driver for golang)
err = databaseConnection.Insert(&customer)
How do I retrieve the customer struct from the DB using parameters from the nested Person struct? E.g. pull all Customer structs that have a Person struct named “John”
I am trying
err = databaseConnection.Find(bson.M{XXXXXXXXX}).All(&resultsB)
but I can’t figure out what XXXXXX should be.
You could try something like that: bson.M{"person.name": "john"}
check mongodb documentation on embedded documents: https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
Related
import FirebaseFirestoreSwift
import Firebase
// I created this object so that i can map the users data and access it threw this object. example I could say thigs like user.username
// The decodable protocall will read the data dictonary and looks for the exact name for the keys/property names I have listed in the data dictonary, this makes life easier when working with objects and downloading information from an api
struct User: Identifiable, Decodable {
// Im able to delete the uid field out of firebase because this will read the documentID from firebase and store it in this id property, so that I dont have to dupicate that data in the actual body of the object
#DocumentID var id: String?
let username: String
let fullname: String
let profileImageUrl: String
let email: String
let stats: UserStats
// This is a computed property saying if the currently logged in user's id is equal to the id on my object (#DocumentID)
var isCurrentUser: Bool { return Auth.auth().currentUser?.uid == id }
}
struct UserStats: Decodable {
let followers: Int
let following: Int
}
Add ? at the end of each variable.
#FirestoreQuery does little error handling when it comes to decoding.
Also, if you are not using #FirestoreQuery use do try catch instead of try?
I am trying to follow the Model View ViewModel format for SwiftUI, but am running into an issue with UUID. I have an object of type TimeCode that has an attribute id of type UUID (TimeCode is created in xcdatamodels as a CoreData model). In order to create a TimeCodeViewModel object, I need to assign the id attribute in TimeCodeViewModel with the same UUID from the original TimeCode object. I therefore created this class definition to do so:
class TimeCodeViewModel: Identifiable {
var id: UUID
var fullName = ""
init(timeCode: TimeCode) {
self.id = timeCode.id
self.fullName = timeCode.fullName
}
// class methods
}
However, I get a compile time error saying that UUID is a get-only property. This makes sense, since you shouldn't be able to reassign the unique ID of an object to a different object, but in this case I am actually trying to describe the same object. Is it possible to assign self.id with the same UUID?
I guess another approach could be to make the UUID a string and then assign it to the view model, but is it then possible to convert the string back into a UUID? For example, I want to fetch the original TimeCode from CoreData using the UUID from the TimeCodeViewModel so I can save edits to other attributes of the TimeCode.
It would be interesting to see how the TimeCode Class looks like. I don't think that the id is set correctly. If you want a unique identifier as a String add the following to generate one:
var id: String = UUID().uuidString
You can share the string and therefore reference to the same object.
EDIT:
Regarding the new information, changing the class to the following might be an idea:
class TimeCodeViewModel: Identifiable {
var id: UUID {
return timeCode.id
}
var fullName = ""
private var timeCode: TimeCode
init(timeCode: TimeCode) {
self.timeCode = timeCode
self.fullName = timeCode.fullName
}
// class methods
}
import (
"gorm.io/gorm"
"gorm.io/driver/postgres"
)
type School struct {
gorm.Model
Students []Student `json:"students"`
}
type Student struct {
gorm.Model
Name string `json:"name"`
}
func init() {
//connect to db first
conn, err := gorm.Open(postgres.New(postgres.Config{
DSN: dbUri,
PreferSimpleProtocol: true,
}), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
db = conn
db.AutoMigrate(&Student{}, &School{})
}
Create the structs and automigrating it gives me an error. Do you know why this is? Also how to you work with has many relation in gorm, what kind of data does it create in postgres?
Error -
Need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
You need to add a SchoolID field to your Student. See the docs here for full usage.
type Student struct {
gorm.Model
SchoolID uint
Name string `json:"name"`
}
To answer the second part, it will create two tables for you. Schools and students. The students will have a foreign key that points to the ID of a school. I would read the docs to learn how this works more.
I have two structs with a many-to-many relation like this:
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
gorm.Model
Name string
}
I want to find users who have specified language. something like this:
var users []User
var lang = Language <-- this is the specified language
db.Model(&user).Association("Languages").Where("id = ? ", lang.ID).Find(&users)
but this format is not allowed.
I found the solution myself. for finding Users who have specified language must use Back-Reference like this:
type User struct {
gorm.Model
Languages []*Language `gorm:"many2many:user_languages;"`
}
type Language struct {
gorm.Model
Name string
Users []*User `gorm:"many2many:user_languages;"`
}
and the query will be in this form:
var users []User
var lang = Language <-- this is the specified language
db.Model(&lang).Association("Users").Find(&users)
I have the following pieces of code:
Interface & function definition:
package helper
import "gopkg.in/mgo.v2/bson"
// Defines an interface for identifiable objects
type Identifiable interface {
GetIdentifier() bson.ObjectId
}
// Checks if a slice contains a given object with a given bson.ObjectId
func IsInSlice(id bson.ObjectId, objects []Identifiable) bool {
for _, single := range objects {
if single.GetIdentifier() == id {
return true
}
}
return false
}
The definition of the user struct which satisfies 'Identifiable':
package models
import (
"github.com/my/project/services"
"gopkg.in/mgo.v2/bson"
)
type User struct {
Id bson.ObjectId `json:"_id,omitempty" bson:"_id,omitempty"`
Username string `json:"username" bson:"username"`
Email string `json:"email" bson:"email"`
Password string `json:"password" bson:"password"`
Albums []bson.ObjectId `json:"albums,omitempty" bson:"albums,omitempty"`
Friends []bson.ObjectId `json:"friends,omitempty" bson:"friends,omitempty"`
}
func GetUserById(id string) (err error, user *User) {
dbConnection, dbCollection := services.GetDbConnection("users")
defer dbConnection.Close()
err = dbCollection.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&user)
return err, user
}
func (u *User) GetIdentifier() bson.ObjectId {
return u.Id
}
A test which checks for the existence of an object inside a slice:
package controllers
import (
"github.com/my/project/helper"
"gopkg.in/mgo.v2/bson"
)
var testerId = bson.NewObjectId()
var users = []models.Users{}
/* Some code to get users from db */
if !helper.IsInSlice(testerId, users) {
t.Fatalf("User is not saved in the database")
}
When I try to compile the test it I get the error: undefined helper.IsInSlice. When I rewrite the IsInSlice method to not take []Identifiable but []models.User it works fine.
Any ideas?
Your problem is that you're trying to use a value of type []models.Users{} as a value of type []Identifiable. While models.Users implements Identifiable, Go's type system is designed so that slices of values implementing an interface cannot be used as (or converted to) slices of the interface type.
See the Go specification's section on conversions for more details.
Apparently, Go did not rebuild my package and was looking for the function in an old build. It was therefore undefined. Performing rm -fr [GO-ROOT]/pkg/github.com/my/project/models did the trick.