ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

golang操作mongo

2020-08-20 10:31:18  阅读:304  来源: 互联网

标签:mongo err fmt DB golang context 操作 bson constants


本文采用mongo-driver/mongo驱动操作数据库

设计mongo插件结构

将代码分为如下结构
model : odm模型,主要是映射为数据库存储的表结构
constants : 存储一些常量
config : mongo的配置信息,比如空闲时长,连接数,超时时间等
mongodb : 实现了mongo的连接和关闭等功能。

目录结构如下
1.png

mongo的连接和断开

在mongodb.go中实现了连接和断开操作
初始化

var (
	DB *Database
)

type Database struct {
	Mongo *mongo.Client
}

//初始化
func Init() {
	DB = &Database{
		Mongo: SetConnect(),
	}
}

  

连接数据库 

func SetConnect() *mongo.Client {

	var retryWrites bool = false

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	clientOptions := options.Client().SetHosts(config.GetConf().MongoConf.Hosts).
		SetMaxPoolSize(config.GetConf().MongoConf.MaxPoolSize).
		SetHeartbeatInterval(constants.HEART_BEAT_INTERVAL).
		SetConnectTimeout(constants.CONNECT_TIMEOUT).
		SetMaxConnIdleTime(constants.MAX_CONNIDLE_TIME).
		SetRetryWrites(retryWrites)

	//设置用户名和密码
	username := config.GetConf().MongoConf.Username
	password := config.GetConf().MongoConf.Password

	if len(username) > 0 && len(password) > 0 {
		clientOptions.SetAuth(options.Credential{Username: username, Password: password})
	}

	client, err := mongo.Connect(ctx, clientOptions)
	if err != nil {
		fmt.Println(err)
	}

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

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println("Connected to MongoDB!")

	return client
}

  

关闭数据库 

func Close() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	DB.Mongo.Disconnect(ctx)
}

  

在model中定义模型 

定义的模型加上bson标签,这样可以映射到数据库里了

type UserData struct {
	Id         string `bson:"_id,omitempty" json:"id"`
	Name       string `bson:"name" json:"name"`
	Number     int    `bson:"number" json:"number"`
	Age        int    `bson:"age" json:"age"`
	BirthMonth int    `bson:"birthMonth" json:"birthMonth"`
}

 

在main函数中实现一些demo 

在main函数中实现一些demo,包括单条插入,多条插入,单条更新,多条更新,分组查询,分页查询
1 单条插入

//单条插入
func insertOne() {
	client := mongodb.DB.Mongo
	// 获取数据库和集合
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)
	userdata := model.UserData{}
	userdata.Age = 13
	userdata.BirthMonth = 11
	userdata.Number = 3
	userdata.Name = "zack"
	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	// 插入一条数据
	insertOneResult, err := collection.InsertOne(ctx, &userdata)
	if err != nil {
		fmt.Println("insert one error is ", err)
		return
	}
	log.Println("collection.InsertOne: ", insertOneResult.InsertedID)
	//将objectid转换为string
	docId := insertOneResult.InsertedID.(primitive.ObjectID)
	recordId := docId.Hex()
	fmt.Println("insert one ID str is :", recordId)
}


2 多条插入 

//多条插入
func insertMany() {
	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	client := mongodb.DB.Mongo
	// 获取数据库和集合
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)
	userdata1 := model.UserData{}
	userdata1.Age = 20
	userdata1.BirthMonth = 11
	userdata1.Number = 4
	userdata1.Name = "Lilei"

	userdata2 := model.UserData{}
	userdata2.Age = 20
	userdata2.BirthMonth = 12
	userdata2.Number = 5
	userdata2.Name = "HanMeiMei"

	var list []interface{}
	list = append(list, &userdata1)
	list = append(list, &userdata2)
	result, err := collection.InsertMany(ctx, list)
	if err != nil {
		fmt.Println("insert many error is ", err)
	}
	fmt.Println("insert many success, res is ", result.InsertedIDs)
}


3 查找单条 

//查找单个
func findOne() {

	client := mongodb.DB.Mongo
	// 获取数据库和集合
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)
	filter := bson.M{"name": "HanMeiMei"}

	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	singleResult := collection.FindOne(ctx, filter)
	if singleResult == nil || singleResult.Err() != nil {
		fmt.Println("find one error is ", singleResult.Err().Error())
		return
	}

	userData := &model.UserData{}
	err := singleResult.Decode(userData)
	if err != nil {
		fmt.Println("find one failed error is ", err)
		return
	}

	fmt.Println("find one success, res is ", userData)
}


4 查找多条 

//查询多个结果集,用cursor
func findMany() {
	client := mongodb.DB.Mongo
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)

	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	filter := bson.M{"birthMonth": bson.M{"$lte": 12}}

	cursor, err := collection.Find(ctx, filter)
	if err != nil {
		fmt.Println("find res failed , error is ", err)
		return
	}
	defer cursor.Close(context.Background())

	result := make(map[string]*model.UserData)
	for cursor.Next(context.Background()) {
		ud := &model.UserData{}
		err := cursor.Decode(ud)
		if err != nil {
			fmt.Println("decode error is ", err)
			continue
		}
		result[ud.Name] = ud
	}

	fmt.Println("success is ", result)
	return
}


5 更新一条 

//更新
func updateOne() {
	client := mongodb.DB.Mongo
	collection, _ := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION).Clone()
	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	/*
		oid, err := primitive.ObjectIDFromHex(obj.RecordId)
		if err != nil {
			logging.Logger.Info("convert string from object failed")
			return err
		}
		filter := bson.M{"_id": oid}
	*/
	filter := bson.M{"name": "zack"}
	value := bson.M{"$set": bson.M{
		"number": 1024}}

	_, err := collection.UpdateOne(ctx, filter, value)
	if err != nil {
		fmt.Println("update user data failed, err is ", err)
		return
	}
	fmt.Println("update success !")
	return
}


6 更新多条 

//更新多条记录
func updateMany() {
	client := mongodb.DB.Mongo
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)

	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	var names = []string{"zack", "HanMeiMei"}
	filter := bson.M{"name": bson.M{"$in": names}}

	value := bson.M{"$set": bson.M{"birthMonth": 3}}
	result, err := collection.UpdateMany(ctx, filter, value)
	if err != nil {
		fmt.Println("update many failed error is ", err)
		return
	}
	fmt.Println("update many success !, result is ", result)
	return
}

 

7 分组查询 

//分组查询
func findGroup() {
	client := mongodb.DB.Mongo
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)

	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()
	//复杂查询,先匹配后分组
	pipeline := bson.A{
		bson.M{
			"$match": bson.M{"birthMonth": 3},
		},
		bson.M{"$group": bson.M{
			"_id":        bson.M{"birthMonthUid": "$birthMonth"},
			"totalCount": bson.M{"$sum": 1},
			"nameG":      bson.M{"$min": "$name"},
			"ageG":       bson.M{"$min": "$age"},
		},
		},

		//bson.M{"$sort": bson.M{"time": 1}},
	}
	fmt.Println("pipeline is ", pipeline)

	cursor, err := collection.Aggregate(ctx, pipeline)
	fmt.Println("findGroup cursor is ", cursor)
	if err != nil {
		fmt.Printf("dao.findGroup collection.Aggregate() error=[%s]\n", err)
		return
	}

	for cursor.Next(context.Background()) {
		doc := cursor.Current

		totalCount, err_2 := doc.LookupErr("totalCount")
		if err_2 != nil {
			fmt.Printf("dao.findGroup totalCount err_2=[%s]\n", err_2)
			return
		}

		nameData, err_4 := doc.LookupErr("nameG")
		if err_4 != nil {
			fmt.Printf("dao.findGroup insertDateG err_4=[%s]\n", err_4)
			return
		}

		ageData, err_5 := doc.LookupErr("ageG")
		if err_5 != nil {
			fmt.Printf("dao.findGroup ageG err_5=[%s]\n", err_5)
			continue
		}
		fmt.Println("totalCount is ", totalCount)
		fmt.Println("nameData is ", nameData)
		fmt.Println("ageData is ", ageData)
	}
}

  


8 分页查询 

//分页查询
func limitPage() {
	client := mongodb.DB.Mongo
	collection := client.Database(constants.DB_DATABASES).Collection(constants.DB_COLLECTION)

	ctx, cancel := context.WithTimeout(context.Background(), constants.QUERY_TIME_OUT)
	defer cancel()

	filter := bson.M{"age": bson.M{"$gte": 0}}

	SORT := bson.D{{"number", -1}}
	findOptions := options.Find().SetSort(SORT)
	//从第1页获取,每次获取10条
	skipTmp := int64((1 - 1) * 10)
	limitTmp := int64(10)
	findOptions.Skip = &skipTmp
	findOptions.Limit = &limitTmp
	cursor, err := collection.Find(ctx, filter, findOptions)
	defer cursor.Close(context.Background())
	if err != nil {
		fmt.Println("limit page error is ", err)
		return
	}

	for cursor.Next(context.Background()) {
		ud := &model.UserData{}
		err := cursor.Decode(ud)
		if err != nil {
			fmt.Println("user data decode error is ", err)
			continue
		}

		fmt.Println("user data is ", ud)

	}
}

  


源码地址 

可以下载源码,二次封装放到项目中直接使用
https://github.com/secondtonone1/golang-/tree/master/gomongo

感谢关注公众号

wxgzh.jpg

标签:mongo,err,fmt,DB,golang,context,操作,bson,constants
来源: https://www.cnblogs.com/secondtonone1/p/13533650.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有