在调用 Execute 之前,插入操作必须有一个部署集

Sid*_*h V 3 amazon-ec2 go mongodb

我有一个运行 MongoDB 的 AWS 实例。我正在尝试做一个小的 db 操作,当下面包含的文件被写入单个 go 文件时,它似乎工作。当我尝试拆分它时,出现以下错误

在调用 Execute 之前,插入操作必须有一个部署集

拆分文件如下

去连接

package db

import (
	"context"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var Client1 mongo.Client

func Connect() {
	// Set client options
	clientOptions := options.Client().ApplyURI("remote_url")

	// Connect to MongoDB
	Client1, err := mongo.Connect(context.TODO(), clientOptions)

	if err != nil {
		log.Fatal(err)
	}

	// Check the connection
	err = Client1.Ping(context.TODO(), nil)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Connected to MongoDB!")
}

func main() {
	fmt.Println("Connection to MongoDB done.")
}
Run Code Online (Sandbox Code Playgroud)

main.go

package main

import (
	"context"
	"fmt"
	"log"

	"db"

	"go.mongodb.org/mongo-driver/bson"
)

// You will be using this Trainer type later in the program
type Trainer struct {
	Name string
	Age  int
	City string
}

func main() {

	db.Connect()
	collection := db.Client1.Database("test2").Collection("trainers")
	_ = collection

	fmt.Println("Created collection", _)

	ash := Trainer{"Ash", 10, "Pallet Town"}
	// misty := Trainer{"Misty", 10, "Cerulean City"}
	// brock := Trainer{"Brock", 15, "Pewter City"}

	insertResult, err := collection.InsertOne(context.TODO(), ash)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Inserted a single document: ", insertResult)

	err = db.Client1.Disconnect(context.TODO())

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connection to MongoDB closed.")
}
Run Code Online (Sandbox Code Playgroud)

它们被放置在以下结构中

/src -> main.go
/src -> /db/connect.go

SPM*_*SPM 5

我相信您的问题是由变量阴影wiki)引起的,并且您正在初始化一个局部变量而不是全局mongo.Client对象,因此抛出了您遇到的错误

它发生在您的connect.go文件中,您在其中定义了两个Client1具有相同名称的不同变量:

  1. 一个在全球范围内
  2. 另一个在Connect()调用时被声明+初始化mongo.Connect()

    var Client1 mongo.Client // Client1 at global scope
    
    func Connect() {
        // Set client options
        clientOptions := options.Client().ApplyURI("remote_url")
    
        // Connect to MongoDB
        Client1, err := mongo.Connect(context.TODO(), clientOptions) // Client1 at local scope within Connect()
    
    Run Code Online (Sandbox Code Playgroud)

这导致全局范围内的那个从未初始化,因此 main.go 在尝试使用它时崩溃,因为它为零。

有几种方法可以解决这个问题,例如在局部范围内为变量使用不同的名称并将客户端分配给全局变量:

    var Client1 mongo.Client

    func Connect() {
        // Set client options
        clientOptions := options.Client().ApplyURI("remote_url")

        // Connect to MongoDB
        Client1Local, err := mongo.Connect(context.TODO(), clientOptions)
        Client1 = *Client1Local
Run Code Online (Sandbox Code Playgroud)

或者避免声明局部变量并直接在全局范围内初始化:

    var Client1 *mongo.Client // Note that now Client1 is of *mongo.Client type

    func Connect() {
        // Set client options
        clientOptions := options.Client().ApplyURI("remote_url")

        // Connect to MongoDB
        var err error
        Client1, err = mongo.Connect(context.TODO(), clientOptions) // Now it's an assignment, not a declaration+assignment anymore
Run Code Online (Sandbox Code Playgroud)

Issue#377 提案中更多关于 Golang 的变量阴影讨论