英文:
Golang unable to create a document in MongoDB
问题
我正在尝试将一个文档插入到MongoDB中,但是尽管成功连接到Mongo,但我一直收到以下错误:
http: panic serving 172.27.0.8:40176: runtime error: invalid memory address or nil pointer dereference
我的main.go文件中,我正在初始化数据库连接,代码如下:
func main(){
//连接到Mongo
mongoClient,err:=connectToMongo()
if err!=nil{
log.Panic(err)
}
client=mongoClient
//创建一个Mongo需要的上下文以便断开连接
ctx,_:=context.WithTimeout(context.Background(), 15*time.Second)
//关闭连接
defer func () {
if err =client.Disconnect(ctx); err!=nil{
panic(err)
}
}()
muxRouter := mux.NewRouter().StrictSlash(true)
//指定允许连接的来源
c:=cors.New(cors.Options{
AllowedOrigins: []string{"https://*", "http://*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
ExposedHeaders: []string{"Link"},
AllowCredentials: true,
MaxAge: 300,
})
router := AddRoutes(muxRouter)
handler := c.Handler(router)
log.Println("Service stratring at o port ",webPort)
sterr := http.ListenAndServe(":9090", handler) //使用docker时取消注释此行
if sterr != nil {
log.Fatal("error starting http server :: ", err)
return
}
log.Println("Service started at port ",webPort)
}
func connectToMongo()(*mongo.Client,error){
mongoUsername := os.Getenv("MONGOUSERNAME")
mongoPassword := os.Getenv("MONGOPASSWORD")
//创建连接选项
clientOptions:=options.Client().ApplyURI(mongoURL)
clientOptions.SetAuth(options.Credential{
Username: mongoUsername,
Password: mongoPassword,
})
//连接
c,err:=mongo.Connect(context.TODO(),clientOptions)
if err!=nil{
log.Println("Error connecting to mongo",err)
return nil,err
}
log.Println("Connected to mongo")
return c,nil
}
在一个单独的models.go文件中,我尝试将数据插入到数据库中,代码如下:
var client *mongo.Client
func Insert(entry LogEntry)error{
log.Printf("Attempting to insert %s", entry)
log.Printf("client s %s", client)
//db:=client.Database("logs")
//log.Printf("database is %s", db)
collection:=client.Database("logs").Collection("logsCollection")
log.Printf("collection is %s", collection)
_,err :=collection.InsertOne(context.TODO(), LogEntry{
Name: entry.Name,
Data: entry.Data,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
})
if err!=nil{
log.Println("Error inserting new record into logs collection",err)
return err
}
log.Println("insert successful")
return nil
}
有人能发现我做错了什么吗?
英文:
I'm trying to insert a document into mongoDB but I keep getting the following error despite successfully managing to connect to mongo:
http: panic serving 172.27.0.8:40176: runtime error: invalid memory address or nil pointer dereference
My main.go where I'm initializing a database connection looks like this
func main(){
//Connect to mongo
mongoClient,err:=connectToMongo()
if err!=nil{
log.Panic(err)
}
client=mongoClient
//Create a context that mongo needs in order to disconnect
ctx,_:=context.WithTimeout(context.Background(), 15*time.Second)
// ctx,cancel:=context.WithTimeout(context.Background(), 15*time.Second)
//defer cancel()
//close connection
defer func () {
if err =client.Disconnect(ctx); err!=nil{
panic(err)
}
}()
muxRouter := mux.NewRouter().StrictSlash(true)
//specify who's allowed to connect
c:=cors.New(cors.Options{
AllowedOrigins: []string{"https://*", "http://*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
ExposedHeaders: []string{"Link"},
AllowCredentials: true,
MaxAge: 300,
})
router := AddRoutes(muxRouter)
handler := c.Handler(router)
log.Println("Service stratring at o port ",webPort)
sterr := http.ListenAndServe(":9090", handler) //Uncomment this line when using docker
if sterr != nil {
log.Fatal("error starting http server :: ", err)
return
}
log.Println("Service started at port ",webPort)
}
func connectToMongo()(*mongo.Client,error){
mongoUsername := os.Getenv("MONGOUSERNAME")
mongoPassword := os.Getenv("MONGOPASSWORD")
//create connection options
clientOptions:=options.Client().ApplyURI(mongoURL)
clientOptions.SetAuth(options.Credential{
Username: mongoUsername,
Password: mongoPassword,
})
//connect
c,err:=mongo.Connect(context.TODO(),clientOptions)
if err!=nil{
log.Println("Error connecting to mongo",err)
return nil,err
}
log.Println("Connected to mongo")
return c,nil
}
In a separate file models.go is where I'm attempting to insert data into the database as follows:
var client *mongo.Client
func Insert(entry LogEntry)error{
log.Printf("Attempting to insert %s", entry)
log.Printf("client s %s", client)
//db:=client.Database("logs")
//log.Printf("database is %s", db)
collection:=client.Database("logs").Collection("logsCollection")
log.Printf("collection is %s", collection)
_,err :=collection.InsertOne(context.TODO(), LogEntry{
Name: entry.Name,
Data: entry.Data,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
})
if err!=nil{
log.Println("Error inserting new record into logs collection",err)
return err
}
log.Println("insert successful")
return nil
}
Can anyone spot what I'm doing wrong?
答案1
得分: 1
由于错误是通用的(例如,没有提供错误的行号),我将分享一个可行的解决方案,也许可以帮助你找出问题所在。让我先分享代码。
main.go
文件
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type LogEntry struct {
Name string
Data string
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
clientOptions := options.Client().ApplyURI("mongodb://root:root@localhost:27017")
mongoClient, err := mongo.Connect(ctx, clientOptions)
if err != nil {
panic(err)
}
defer mongoClient.Disconnect(ctx)
demoDb := mongoClient.Database("demodb")
myCollection := demoDb.Collection("myCollection")
// delete documents
if _, err := myCollection.DeleteMany(ctx, bson.M{}); err != nil {
panic(err)
}
// insert data
insertRes, err := myCollection.InsertOne(ctx, LogEntry{
Name: "lorem ipsum",
Data: "lorem ipsum",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
})
if err != nil {
panic(err)
}
fmt.Println(insertRes.InsertedID)
// query data
cursor, err := myCollection.Find(ctx, bson.M{})
if err != nil {
panic(err)
}
var logEntries []bson.M
if err = cursor.All(ctx, &logEntries); err != nil {
panic(err)
}
for _, v := range logEntries {
fmt.Println(v)
}
}
为了演示的目的,我将所有逻辑放在了一个文件中。在这个文件中,我完成了以下步骤:
- 设置 MongoDB 连接。
- 连接到数据库和其中的一个集合。
- 删除已经存在的所有文档(只是为了更清晰)。
- 在
myCollection
集合中插入一个新的LogEntry
实例。 - 检索
myCollection
集合中的所有条目。
最后要提到的是我用于运行容器的 Docker 命令:
docker run -d -p 27017:27017 --name mymongo -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=root mongo:latest
如果你按照我的解决方案进行操作,应该能够成功插入一个文档。如果不是这种情况,请告诉我,我会尽力帮助你!
英文:
As the error is generic (e.g. the line number of the error is not provided) I'm gonna share a working solution that maybe can help you in figuring out what's wrong. Let me share the code first.
main.go
file
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type LogEntry struct {
Name string
Data string
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
clientOptions := options.Client().ApplyURI("mongodb://root:root@localhost:27017")
mongoClient, err := mongo.Connect(ctx, clientOptions)
if err != nil {
panic(err)
}
defer mongoClient.Disconnect(ctx)
demoDb := mongoClient.Database("demodb")
myCollection := demoDb.Collection("myCollection")
// delete documents
if _, err := myCollection.DeleteMany(ctx, bson.M{}); err != nil {
panic(err)
}
// insert data
insertRes, err := myCollection.InsertOne(ctx, LogEntry{
Name: "lorem ipsum",
Data: "lorem ipsum",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
})
if err != nil {
panic(err)
}
fmt.Println(insertRes.InsertedID)
// query data
cursor, err := myCollection.Find(ctx, bson.M{})
if err != nil {
panic(err)
}
var logEntries []bson.M
if err = cursor.All(ctx, &logEntries); err != nil {
panic(err)
}
for _, v := range logEntries {
fmt.Println(v)
}
}
For the sake of the demo, I put all of the logic inside a single file. Within this file, I did the following steps:
- Set up a MongoDB connection.
- Connect to a database and to a collection within that database.
- Delete all of the documents that were already there (just to be clearer).
- Insert a new
LogEntry
instance in themyCollection
collection. - Retrieve all of the entries in the
myCollection
collection.
Last thing to mention is the Docker command I used to run my container:
docker run -d -p 27017:27017 --name mymongo -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=root mongo:latest
If you stick to my solution, you should be able to insert a document without any issue. If not the case, just let me know and I'll try to help you!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论