zoukankan      html  css  js  c++  java
  • Golang使用MongoDB通用操作

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

    3、查询文档的_id

    var result interface{}
    err = c.Find(bson.M{"username": "impressionw"}).Select(bson.M{"_id": 1}).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": 1}}})
    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": 1}).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": 1}, "$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": -1}}
    err := c.Update(bson.M{"username": "impressionw"}, option)

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

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

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

    err := session.DB("PersonManage").C("Persons").Remove(bson.M{"_id":bson.ObjectIdHex("5b6c0536a8ab29200debcb0b")})
  • 相关阅读:
    OC UITextField只允许输入两位小数
    UIBezierPath使用
    2020-11-25:go中,map的底层数据结构是什么?
    2020-11-24:n个物品每个物品都有一定价值,分给2个人,怎么分两个人的价值差最小?
    2020-11-23:go中,s是一个字符串,s[0]代表什么?是否等于固定字节数?
    2020-11-22:mysql中,什么是filesort?
    2020-11-21:java中,什么是跨代引用?
    2020-11-20:java中,听说过CMS的并发预处理和并发可中断预处理吗?
    2020-11-19:go中,defer原理是什么?
    2020-11-18:java中,到底多大的对象会被直接扔到老年代?
  • 原文地址:https://www.cnblogs.com/dfsxh/p/10208780.html
Copyright © 2011-2022 走看看