Skip to content

mongodb

在 Go 中使用 MongoDB,一般通过第三方库来实现,最常用的库是 go.mongodb.org/mongo-driver,这是官方推荐的 MongoDB Go 客户端。它支持 MongoDB 的常见操作,如增、删、改、查等,并提供了丰富的功能来管理数据库连接、执行查询和处理 BSON 数据。

1. 安装 MongoDB Go 驱动

首先,你需要安装 MongoDB Go 驱动:

bash
go get go.mongodb.org/mongo-driver/mongo
go get go.mongodb.org/mongo-driver/bson

2. 基本操作

2.1 导入包

go
package main

import (
	"context"
	"fmt"
	"log"
	"time"

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

2.2 连接 MongoDB 数据库

在 Go 中,你需要使用 mongo.Connect() 方法连接 MongoDB 数据库。通常需要配置连接的 URI、超时设置等。

go
func connectToMongoDB() (*mongo.Client, context.Context, context.CancelFunc) {
	// MongoDB 连接 URI
	uri := "mongodb://localhost:27017"

	// 创建一个新的 context 和取消函数
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)

	// 连接到 MongoDB
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
	if err != nil {
		log.Fatalf("Error connecting to MongoDB: %v", err)
	}

	// 验证连接
	err = client.Ping(ctx, nil)
	if err != nil {
		log.Fatalf("Error pinging MongoDB: %v", err)
	}

	fmt.Println("Connected to MongoDB!")
	return client, ctx, cancel
}

2.3 选择数据库和集合

MongoDB 数据库由多个集合(collection)组成,你可以通过客户端选择某个数据库和集合进行操作。

go
func getCollection(client *mongo.Client, dbName, collectionName string) *mongo.Collection {
	// 获取指定的数据库和集合
	collection := client.Database(dbName).Collection(collectionName)
	return collection
}

2.4 插入文档

MongoDB 使用 BSON 格式存储数据。在 Go 中,你可以使用 bson.Dbson.M 来构建文档。

go
func insertDocument(collection *mongo.Collection) {
	// 创建文档
	document := bson.D{
		{"name", "Alice"},
		{"age", 30},
		{"city", "New York"},
	}

	// 插入文档
	_, err := collection.InsertOne(context.Background(), document)
	if err != nil {
		log.Fatalf("Error inserting document: %v", err)
	}

	fmt.Println("Document inserted")
}

2.5 查找文档

你可以使用 FindOneFind 来查询 MongoDB 中的文档。

go
func findDocument(collection *mongo.Collection) {
	var result bson.M

	// 查找第一个匹配的文档
	err := collection.FindOne(context.Background(), bson.M{"name": "Alice"}).Decode(&result)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			fmt.Println("No documents found")
		} else {
			log.Fatalf("Error finding document: %v", err)
		}
	}

	// 打印查询结果
	fmt.Println("Found document:", result)
}

2.6 更新文档

更新文档时,使用 UpdateOneUpdateMany 方法。

go
func updateDocument(collection *mongo.Collection) {
	// 定义更新条件和更新内容
	filter := bson.M{"name": "Alice"}
	update := bson.M{
		"$set": bson.M{"age": 31}, // 设置新的值
	}

	// 执行更新
	_, err := collection.UpdateOne(context.Background(), filter, update)
	if err != nil {
		log.Fatalf("Error updating document: %v", err)
	}

	fmt.Println("Document updated")
}

2.7 删除文档

使用 DeleteOneDeleteMany 删除文档。

go
func deleteDocument(collection *mongo.Collection) {
	// 删除符合条件的第一个文档
	_, err := collection.DeleteOne(context.Background(), bson.M{"name": "Alice"})
	if err != nil {
		log.Fatalf("Error deleting document: %v", err)
	}

	fmt.Println("Document deleted")
}

2.8 查找多个文档

使用 Find 来查询多个文档,并将结果存入切片中。

go
func findAllDocuments(collection *mongo.Collection) {
	// 查找所有文档
	cursor, err := collection.Find(context.Background(), bson.M{})
	if err != nil {
		log.Fatalf("Error finding documents: %v", err)
	}
	defer cursor.Close(context.Background())

	// 创建一个切片存储结果
	var results []bson.M
	for cursor.Next(context.Background()) {
		var result bson.M
		if err := cursor.Decode(&result); err != nil {
			log.Fatalf("Error decoding document: %v", err)
		}
		results = append(results, result)
	}

	// 打印结果
	fmt.Println("Found documents:", results)
}

3. 完整示例

下面是一个完整的示例,展示了如何连接到 MongoDB、插入、查询、更新和删除文档:

go
package main

import (
	"context"
	"fmt"
	"log"
	"time"

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

func connectToMongoDB() (*mongo.Client, context.Context, context.CancelFunc) {
	uri := "mongodb://localhost:27017"
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
	if err != nil {
		log.Fatalf("Error connecting to MongoDB: %v", err)
	}
	err = client.Ping(ctx, nil)
	if err != nil {
		log.Fatalf("Error pinging MongoDB: %v", err)
	}
	fmt.Println("Connected to MongoDB!")
	return client, ctx, cancel
}

func getCollection(client *mongo.Client, dbName, collectionName string) *mongo.Collection {
	return client.Database(dbName).Collection(collectionName)
}

func insertDocument(collection *mongo.Collection) {
	document := bson.D{
		{"name", "Alice"},
		{"age", 30},
		{"city", "New York"},
	}
	_, err := collection.InsertOne(context.Background(), document)
	if err != nil {
		log.Fatalf("Error inserting document: %v", err)
	}
	fmt.Println("Document inserted")
}

func findDocument(collection *mongo.Collection) {
	var result bson.M
	err := collection.FindOne(context.Background(), bson.M{"name": "Alice"}).Decode(&result)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			fmt.Println("No documents found")
		} else {
			log.Fatalf("Error finding document: %v", err)
		}
	}
	fmt.Println("Found document:", result)
}

func updateDocument(collection *mongo.Collection) {
	filter := bson.M{"name": "Alice"}
	update := bson.M{
		"$set": bson.M{"age": 31},
	}
	_, err := collection.UpdateOne(context.Background(), filter, update)
	if err != nil {
		log.Fatalf("Error updating document: %v", err)
	}
	fmt.Println("Document updated")
}

func deleteDocument(collection *mongo.Collection) {
	_, err := collection.DeleteOne(context.Background(), bson.M{"name": "Alice"})
	if err != nil {
		log.Fatalf("Error deleting document: %v", err)
	}
	fmt.Println("Document deleted")
}

func main() {
	client, ctx, cancel := connectToMongoDB()
	defer cancel()

	collection := getCollection(client, "testdb", "users")

	// 插入文档
	insertDocument(collection)

	// 查找文档
	findDocument(collection)

	// 更新文档
	updateDocument(collection)

	// 删除文档
	deleteDocument(collection)
}

4. 其他常见操作

  • 批量插入:

    使用 InsertMany 插入多个文档:

    go
    documents := []interface{}{
        bson.D{{"name", "Bob"}, {"age", 25}},
        bson.D{{"name", "Charlie"}, {"age", 35}},
    }
    
    _, err := collection.InsertMany(context.Background(), documents)
    if err != nil {
        log.Fatalf("Error inserting multiple documents: %v", err)
    }
  • 创建索引:

    go
    indexModel := mongo.IndexModel{
        Keys: bson.M{"name": 1}, // 按照 "name" 字段升序排序
        Options: options.Index().SetUnique(true),
    }
    
    _, err := collection.Indexes().CreateOne(context.Background(), indexModel)
    if err != nil {
        log.Fatalf("Error creating index: %v", err)
    }

总结

通过 go.mongodb.org/mongo-driver/mongo 驱动,你可以在 Go 中轻松实现与 MongoDB 的集成。常见的操作包括连接数据库、插入