go 连接 mongodb
go 使用 mongo-go-driver 进行 mongodb数据库连接操作
基本使用
使用: mongo-go-driver
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
// 设置客户端连接配置(connect=direct当数据库为集群时,可通过配置此项解决此驱动连接docker方式部署的mongodb集群由于docker方式部署的访问域名连接,而外面的网络访问不到的情况) mongodb://user:password@ip:port/database?connect=direct
// &replicaSet=集群名称 authSource=数据库名称 此配置也可以指定数据库
clientOptions := options.Client().ApplyURI("mongodb://用户:密码@地址:27017/数据库?connect=direct")
// 连接到MongoDB
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
}
// 检查连接
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB!")
}
简单封装使用
调用入口:
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
//"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
// 定义 mongodb 数据库连接 url 常量
const MONGODB_URL = "mongodb://用户:密码@地址:27017/数据库?connect=direct"
func main() {
// 定义连接使用的上下文-10秒过期
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
// 进行连接并获取到 client
client, err := mongo.Connect(ctx, options.Client().ApplyURI(MONGODB_URL))
if err != nil {
log.Fatal(err)
}
// 插入数据
// _id, err := insert(client, "数据库", "集合", bson.M{"name": "pi_t", "value": 33333})
// fmt.Println(_id)
// 查询
results, err := finds(client, "数据库", "集合", bson.M{"name": "pi_t"})
// 长度
fmt.Println(len(results))
// 遍历结果中的值
for index := range results {
fmt.Println(results[index]["name"])
}
if err != nil {
log.Fatal(err)
}
}
- 插入文档
// 插入文档
func insert(client *mongo.Client, databaseName string, collectionName string, document interface{},
opts ...*options.InsertOneOptions) (interface{}, error) {
// 指定数据库集合
collection := client.Database(databaseName).Collection(collectionName)
// 插入数据到集合
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
res, err := collection.InsertOne(ctx, document, opts...)
// 返回插入的ID
return res.InsertedID, err
}
- 查询文档
// 查询
func finds(client *mongo.Client, databaseName string, collectionName string, filter interface{},
opts ...*options.FindOptions) ([]bson.M, error) {
// 指定数据库集合
collection := client.Database(databaseName).Collection(collectionName)
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
cur, err := collection.Find(ctx, filter, opts...)
if err != nil {
log.Fatal(err)
}
defer cur.Close(ctx)
// 定义存储结果的数组
var results []bson.M
for cur.Next(ctx) {
var result bson.M
err := cur.Decode(&result)
if err != nil {
log.Fatal(err)
}
// 添加到数组
results = append(results, result)
}
if err := cur.Err(); err != nil {
log.Fatal(err)
}
// 返回结果
return results, err
}
常见错误
-
ReplicaSetNoPrimary
详细错误: (见于连接docker
部署的mongodb
集群,主要原因是mongo-go-driver
连接集群会根据docker
部署的集群服务名进行连接,而由于服务名是在docker
的网络中有效,所以会导致找不到主机名进而连接不上,具体可参考:https://stackoverflow.com/questions/56393513/docker-and-mongo-go-driver-server-selection-error)
current topology: Type: ReplicaSetNoPrimary
Servers:
Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host
Addr: mongo3:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo3: no such host
Addr: mongo1:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo1: no such host
解决方法:
- 把程序在
docker
集群的网络进行部署 - 以
connect=direct
的方式连接,即在连接URL
配置中添加此项 - 集群部署方式改变
- 连接非集群的
mongodb