MongoDB是Nosql中常用的一种数据库,今天笔者就简单总结一下Golang如何使用这些通用的供能的,不喜勿喷。。。

研究的事例结构如下:

type LikeBest struct {
AuthorName string `bson:"authorname,omitempty"`
BookName string `bson:"bookname,omitempty"`
PublishTime string `bson:"publishtime,omitempty"`
LastReadTime string `bson:"lastreadtime,omitempty"`
} type Personnal struct {
UserName string `bson:"username,omitempty"`
WhereCity string `bson:"wherecity,omitempty"`
BookSCount int `bson:"bookscount,omitempty"`
FavoriteBooks []LikeBest `bson:"favoratebooks,omitempty"`
}

建立与MongoDB的连接

session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close() c := session.DB("PersonManage").C("Persons")

注意:以下操作条件默认均为:username=”impressionw”

插入数据
1、使用Insert()函数是最简单且通用的方式

err := c.Insert(&p) //p为插入的结构体数据
2、使用upsert()函数【更新或插入】

change := mgo.Change{
Update: bson.M{"$set": p},
ReturnNew: false,
Remove: false,
Upsert: true,
}
_, err := c.Find(bson.M{"username": "impressionw"}).Apply(change, nil)

或许,你觉得第一种方式更简洁,但是实际场景中,第二种也非常实用
1. 它不仅只能插入数据,Update字段可以接收多个参数插入,但是关键字不能相同【不能同时有2个”$set”】
2. 它能返回处理前或处理后的document,若返回,则Apply的第二个参数即是结果
3. 它可以结合select使用

注意:$set 只修改指定字段的值,不影响其他值
查询数据
1、查询整个文档

err = c.Find(bson.M{"username": "impressionw"}).One(&result)

2、只返回 FavoriteBooks 对应的字段,忽略其他信息
这里用到了Select(),select可以设置,返回的内容:

select{‘filedname’:},表示忽略该字段则结果不返回此字段
select{‘filedname’:},表示关注该字段则只返回关注字段
err = c.Find(bson.M{"username": "impressionw"}).Select(bson.M{"favoratebooks": }).One(&result)

3、查询文档的_id

var result interface{}
err = c.Find(bson.M{"username": "impressionw"}).Select(bson.M{"_id": }).One(&result) var document_id string
switch value := result.(type) {
case bson.M:
mapid := value["_id"]
if mapid != nil {
id := mapid.(bson.ObjectId)
document_id = id.Hex()
}
}

注意:若是查找username含有”impressionw”的文档,可用正则匹配查找,条件这样写:

query = bson.M{"username": bson.M{"$regex": "impressionw"}}
4、查询数组中匹配元素,只返回含有匹配元素的文档,需要用到Mongdob的聚合aggregate

相关操作符的含义如下:

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
match:用于过滤数据,只输出符合条件的文档。match:用于过滤数据,只输出符合条件的文档。match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
下面的代码,将只返回FavorateBooks字段中,bookname为”The Go Programming Language”的书籍,且只关注favoratebooks,不会输出个人信息

pipe := c.Pipe([]bson.M{{"$unwind": "$favoratebooks"},
{"$match": bson.M{"username": "impressionw", "favoratebooks.bookname": "The Go Programming Language"}},
{"$project": bson.M{"favoratebooks": }}})
resp := []bson.M{}
err := pipe.All(&resp)

这样可以达到目的了

更新文档
1、更新WhereCity字段—关键字 $set,将WhereCity修改为”ShangHai“:

err = c.Update(bson.M{"username": "impressionw"}, bson.M{"$set": bson.M{"wherecity": "ShangHai"}})
2、更新FavoriteBooks中的LastReadTime字段

查询条件:username=”impressionw”、bookname=”The Go Programming Language”,将LastReadTime字段更改为:”Oct 26, 2017”

change := mgo.Change{
Update: bson.M{"$set": bson.M{"favoratebooks.$.lastreadtime": "Oct 26, 2017"}},
ReturnNew: false,
Remove: false,
Upsert: true,
}
query := bson.M{"username": "impressionw", "favoratebooks": bson.M{"$elemMatch": bson.M{"bookname": "The Go Programming Language"}}}
_, err = c.Find(query).Select(bson.M{"favoratebooks.bookname": }).Apply(change, nil)

3、更新一个 FavoriteBooks 的整个数组文档,即新增一本书的信息

给username=”impressionw”的文档新增一条书籍记录,同时将BookSCount字段自增1

Act := []LikeBest{
LikeBest{
AuthorName: "YuHen",
BookName: "Go Learning",
PublishTime: "Dec 27, 2014",
LastReadTime: "Dec 29, 2016",
},
}
change := mgo.Change{
Update: bson.M{"$inc": bson.M{"bookscount": }, "$push": bson.M{"favoratebooks": bson.M{"$each": Act}}},
ReturnNew: false,
Remove: false,
Upsert: true,
}
_, err := c.Find(bson.M{"username": "impressionw"}).Apply(change, nil)

注意:

1、此处可用addToSet代替addToSet代替push,addToSet不会添加已有的数据,addToSet不会添加已有的数据,push 会添加重复的数据,可以分别应用于不同场景
2、$inc 对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作, 值为正数表示自增,值为负数表示自减

删除文档
1、删除喜欢的一本书籍信息,同时喜欢书记数量自减1

var option = bson.M{"$pull": bson.M{"favoratebooks": bson.M{"bookname": "Go Learning"}}, "$inc": bson.M{"bookscount": -}}
err := c.Update(bson.M{"username": "impressionw"}, option)

2、删除所有喜欢的书籍,同时将bookscount字段置为 0

var data = bson.M{"$unset": bson.M{"favoratebooks": true}, "$set": bson.M{"bookscount": }}
err = c.Update(bson.M{"username": "impressionw"}, data)

3、删除整个文档,根据”_id”字段删除文档

err := session.DB("PersonManage").C("Persons").Remove(bson.M{"_id":bson.ObjectIdHex("5b6c0536a8ab29200debcb0b")})

Golang使用MongoDB通用操作的更多相关文章

  1. Golang 对MongoDB的操作简单封装

    使用MongoDB的Go驱动库 mgo,对MongoDB的操作做一下简单封装 初始化 操作没有用户权限的MongoDB var globalS *mgo.Session func init() { s ...

  2. java 对mongodb的操作

    java 对mongodb的操作 1.1连单台mongodb Mongo mg = newMongo();//默认连本机127.0.0.1  端口为27017 Mongo mg = newMongo( ...

  3. MongoDB查询操作限制返回字段的方法

    这篇文章主要介绍了MongoDB查询操作限制返回字段的方法,需要的朋友可以参考下   映射(projection )声明用来限制所有查询匹配文档的返回字段.projection以文档的形式列举结果集中 ...

  4. EasyUI-datagrid数据展示+MongoDB数据操作

    使用EasyUI-datagrid进行数据展示:进行添加,修改,删除操作逻辑代码,数据源来自MongoDB. 一.新建SiteInfo控制器,添加Index页面:http://www.cnblogs. ...

  5. Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作

    2 Mongodb CRUD 操作 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mong ...

  6. Xml通用操作类

    using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Xml ...

  7. [置顶] MongoDB 分布式操作——分片操作

    MongoDB 分布式操作——分片操作 描述: 像其它分布式数据库一样,MongoDB同样支持分布式操作,且MongoDB将分布式已经集成到数据库中,其分布式体系如下图所示: 所谓的片,其实就是一个单 ...

  8. MongoDB学习笔记(五) MongoDB文件存取操作

    由于MongoDB的文档结构为BJSON格式(BJSON全称:Binary JSON),而BJSON格式本身就支持保存二进制格式的数据,因此可以把文件的二进制格式的数据直接保存到MongoDB的文档结 ...

  9. mongodb常用操作语句

    mongodb常用操作语句 A:创建数据表 db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean&g ...

随机推荐

  1. HackerRank - common-child【DP】

    HackerRank - common-child[DP] 题意 给出两串长度相等的字符串,找出他们的最长公共子序列e 思路 字符串版的LCS AC代码 #include <iostream&g ...

  2. Django 知识补漏单例模式

    Django 知识补漏单例模式 单例模式:(说白了就是)创建一个类的实例.在 Python 中,我们可以用多种方法来实现单例模式: 1.文件导入的形式(常用) s1.py class Foo(obje ...

  3. EasyUI中datagrid双击事件

    EasyUI中datagrid双击事件 在jsp文件底部增加代码: <script type="text/javascript"> //数据表双击事件 $('#tabl ...

  4. 什么时候需要用super

    1.子类构造函数调用父类构造函数用super 2.子类重写(覆盖)父类方法后,若想调用父类中被重写的方法,用super 3.未被重写的方法可以直接调用.

  5. vue路由两种传参的区别

    //定义路由 { path:"/detail", name:"detail", component:home } //这种做法是错误的,这是query传参的方式 ...

  6. UIScrollView监听静止的数种情况

    1.直接通过block -(void)testInBlock { //通过block监听 [UIView animateWithDuration:1.0 animations:^{ self.scro ...

  7. github上十二款最著名的Android播放器开源项目

    1.ijkplayer 项目地址: https://github.com/Bilibili/ijkplayer 介绍:Ijkplayer 是Bilibili发布的基于 FFplay 的轻量级 Andr ...

  8. Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)

    Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) A.String Reconstruction B. High Load C ...

  9. ssh登录CentOS服务器(Aliyun)

    ssh登录 (一).在本机使用命令生成ssh密钥:(-C代表注释,如果有多个密钥,加个注释就会很好区分) ssh-keygen -t rsa -C "mingwei" (二).将本 ...

  10. MongoDB在linux下的启动

    最近公司数据库用到MongoDB,而之前只关注知道它是分布式非关系数据库,数据以文档的形式存储,数据格式是类似json的bson格式.而对于具体用法以及java如何调用并没有过多接触,今天花费一天的时 ...