golang-mongodb

0、结构体

type Student struct {     // _id 不用带入
    Name string
    Age int
}

1、连接

  驱动 :github.com/mongodb/mongo-go-driver

  1、普通连接

复制代码
client , err := mongo.Connect(
        context.TODO(),
        options.Client().ApplyURI("mongodb://192.168.6.249:27017"))
    if err != nil {
        fmt.Printf("mongodb connect failed, err : %s\n", err)
        return
    }
    defer func() {
        if err = client.Disconnect(context.TODO()); err != nil {
            fmt.Printf("mongodb disconnect failed, err : %s\n", err)
            return
        }
    }()
复制代码

  2、连接池连接

 

2、插入

  1、插入单条

复制代码
    collection := client.Database("erp").Collection("Student")
    // 插入一条
    s1 := Student{Age: 12, Name: "hello"}
    insertResult, err := collection.InsertOne(context.TODO(), s1)
    if err != nil {
        fmt.Printf("insert mongodb failed , err : %s\n", err)
        return
    }
    fmt.Println("insert a single document: ", insertResult)
复制代码

  2、插入多条

    s2 := Student{Age: 13, Name: "world"}
    insertDocs := []interface{}{s1, s2}
    many, err := collection.InsertMany(context.TODO(), insertDocs)
    fmt.Println(many)  // &{[ObjectID("62fefa56a4e8957a0d611caf") ObjectID("62fefa56a4e8957a0d611cb0")]}

3、删除

  1、单个删除

// 删除单个文档 [有多条也仅仅只删除一条]
deleteResult1, err := collection.DeleteOne(context.TODO(), bson.M{"age": 12})
if err != nil {
    fmt.Printf("delete one doc failed, err : %s\n", err)
    return
}
fmt.Printf("delete %v doc", deleteResult1.DeletedCount)   // 删除文档的个数

  2、删除多个

// 删除所有文档
_, err = collection.DeleteMany(context.TODO(), bson.M{})
if err != nil {
fmt.Printf("delete many doc failed, err : %s\n", err)
return
}

   3、先查询,后删除  FindOneAndDelete

var stu1 Student
collection.FindOneAndDelete(context.TODO(), bson.M{"_id": objectIDHex("62ff34aca744197ad42a3413")})
  .Decode(&stu1)
fmt.Printf("one = %+v", stu1)


 

4、查询

  0、根据 _id 查询

复制代码
func objectIDHex(s string) primitive.ObjectID {
    oid, _ := primitive.ObjectIDFromHex(s)
    return oid
}

var stu Student
collection := client.Database("erp").Collection("Student")
collection.FindOne(context.TODO(), bson.M{"_id": objectIDHex("62ff34aca744197ad42a3413")}).Decode(&stu)
fmt.Printf("one = %+v", stu)
复制代码

 

  1、单个查询

  FindOne
    var stu Student
    filter := bson.M{"age": 13}
    collection.FindOne(context.TODO(), filter).Decode(&stu)
    fmt.Printf("stu ==> %+v\n", stu)

  2、多个查询

  Find
复制代码
// 查询多个文档
    findOptions := options.Find()
    findOptions.SetLimit(3)
    var results []*Student

    // 把 bson.D{{}} 作为一个 filter 来匹配所有文档
    cur, err :=collection.Find(context.TODO(), bson.D{{}}, findOptions)
    if err != nil {
        fmt.Printf("find mongodb failed, err : %s\n", err)
        return
    }
    // 查找多个文档返回一个光标
    // 遍历游标允许我们一次解码一个文档
    for cur.Next(context.TODO()) {
        // 创建一个值,将单个文档解码为该值
        var stu Student
        err := cur.Decode(&stu)
        if err != nil {
            fmt.Printf("mongodb decode, err : %s\n", err)
            return
        }
        results = append(results, &stu)
    }
    defer cur.Close(context.TODO())
    for _, v := range results {
        fmt.Printf("%v\n", v)
    }
复制代码

 

 5、修改

  1 修改单条

   UpdateOne

    // 修改
    filter = bson.M{"name": "world1", "age" : 13}
    update := bson.D{{"$inc", bson.D{{"age" , 1}}}}
    updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
    fmt.Printf("ModifiedCount = %v, MatchedCount = %v,",
        updateResult.ModifiedCount, updateResult.MatchedCount,)

  2 修改多条

  UpdateMany
    // 修改
    filter = bson.M{"name": "world", "age" : 13}
    update := bson.D{{"$inc", bson.D{{"age" , 1}}}}
    updateResult, err := collection.UpdateMany(context.TODO(), filter, update)
    fmt.Printf("ModifiedCount = %v, MatchedCount = %v,",
    updateResult.ModifiedCount, updateResult.MatchedCount,)

   3 修改字段的值 $set

filter := bson.M{"name": "hello", "age" : 12}
many, err := collection.UpdateMany(context.TODO(), filter, 
    bson.M{"$set" : bson.M{"name" : "zhansan"}, "$inc" : bson.M{"age" : 1}})

    4 字段的值增加 $inc

collection := client.Database("erp").Collection("Student")
filter := bson.M{"name": "hello", "age" : 13}
collection.UpdateMany(context.TODO(), filter, bson.M{"$inc": bson.M{"age" : -1}})

    5 从数组中增加一个元素  push($push)

filter := bson.M{"name": "zhansan", "age" : 13}
collection.UpdateMany(context.TODO(), filter, bson.M{"$push": bson.M{"tags" : "Golang"}})

# 如果字段 tags 存在,在tags 数组中添加进去
# 如果字段 tags 不存在,加入一个字段 tags , 并且把 Golang 存进去

    6 从数组中删除一个元素 pull($pull)

filter := bson.M{"name": "zhansan", "age" : 13}
collection.UpdateMany(context.TODO(), filter, bson.M{"$pull": bson.M{"tags" : "Golang"}})

# 不会删除字段,中字段的数组中删除一个元素

   7  先查找,后替换 FindOneAndReplace

  

var stu, stu1 Student
collection.FindOneAndReplace(context.TODO(), bson.M{"_id": objectIDHex("62ff1b1d840c01f2575560c8")},
  bson.M{"age" : 27}).Decode(&stu1)
fmt.Printf("one = %+v", stu1)
仅仅修改 age 的值

 

   8  先查找,后修改 FindOneAndUpdate

collection.FindOneAndUpdate(context.TODO(), bson.M{"_id": objectIDHex("62ff1b1d840c01f2575560c8")}, 
  bson.M{"$set" : bson.M{"age" : 66}}).Decode(&stu1)
fmt.Printf("one = %+v", stu1)   // 输出是修改之前的值

 

6、count 统计数量

  CountDocuments

collection := client.Database("erp").Collection("Student")
var count int64
if count, err = collection.CountDocuments(context.TODO(), bson.M{"age" : 200}); err != nil {
    fmt.Printf("")
}
fmt.Println("count==>", count)

 

7、单条件查询

  1、等于  $eq

collection.Find(context.TODO(), bson.M{"age": 13})

  2、不等于 $ne

collection.Find(context.TODO(), bson.M{"age": bson.M{"$ne":13}})

  3、小于 $lt

collection.Find(context.TODO(), bson.M{"age": bson.M{"$lt":13}})

  4、小于等于 $lte

collection.Find(context.TODO(), bson.M{"age": bson.M{"$lte":13}})

  5、大于

collection.Find(context.TODO(), bson.M{"age": bson.M{"$gt": 13}})

  6、大于等于 $gte

collection.Find(context.TODO(), bson.M{"age": bson.M{"$gte":13}})

  7、in 在数组中 $in

collection.Find(context.TODO(), bson.M{"age": bson.M{"$in": []int{0, 13}}})

  8、not in 不在数组中 $nin

collection.Find(context.TODO(), bson.M{"age": bson.M{"$nin": []int{0, 12, 13, 14}}})

  9、exists 是否包含这个键($exists)

collection.Find(context.TODO(), bson.M{"age1": bson.M{"$exists": true}})

  10、查询键为 null 的字段 [键存在,值为空],也可以查询 nil


cur, err := collection.Find(context.TODO(), 
  bson.M{"name": bson.M{"$in": []interface{}{""} , "$exists": true}})

  11、模糊查询 [暂时不会]

 8、关于数组

  1 、size 数组长度

collection.Find(context.TODO(), bson.M{"tags": bson.M{"$size": 3}})   tags 字段数组长度为3

  2、all 查询数组中包含所有值的匹配(不区分顺序,只看包含不包含)

// mongo tag 字段同时包括 mongodb 和 database
collection.Find(context.TODO(), bson.M{"tags": bson.M{"$all": []string{"mongodb", "database"}}})

  3、满足特定的索引下条件

// 数组索引从0开始,我们匹配第二项就用tags.1作为键

filter := bson.M{"tags.0" : "mongodb"}

  4、精确查找,数量,顺序都要满足

bson.M{"tags": []string{"数学", "大学数学", "高等数学"}}

  5、针对数组中的子文档

 bson.M{"author.name": "纪涵"}

 

8、多条件查询 

  1、and

collection.Find(context.TODO(), 
  bson.M{"age" : 12, "name" : "hello", "age1" : bson.M{"$gt" : 2, "$lt" : 4}})

  2、or

c.Find(bson.M{"$or": []bson.M{bson.M{"name": "Jimmy Kuu"}, bson.M{"age": 31}}}).All(&users)

 

9、sort limit 和 skip

findOptions := options.Find()
findOptions.SetLimit(100)
findOptions.SetSkip(20)
findOptions.SetProjection(bson.M{"name" : 0})
findOptions.SetSort(bson.D{{Key : "name" , Value: 1}})
filter := bson.M{"tags.0" : "mongodb"}
var results []*Student
cur, err :=collection.Find(context.TODO(), filter, findOptions)

 

10、其他函数

  1、distinct 去重

filter := bson.M{"name" : bson.M{"$in" : []string{"world", "world1"}}}
distinct, err := collection.Distinct(context.TODO(), "name", filter)
fmt.Println(len(distinct))

 

  

 

11、聚合操作

  1、概念

         $sum    计算总和           

             $avg     计算平均值

     $min     获取集合中所有文档对应值得最小值  

     $max     获取集合中所有文档对应值得最大值

     $push    将值加入一个数组中,不会判断是否有重复的值

     $addToSet 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。

     $first   根据资源文档的排序获取第一个文档数据。

     $last  根据资源文档的排序获取最后一个文档数据

  2、管道的概念

    $project 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。

    $match  用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。

    $limit  用来限制MongoDB聚合管道返回的文档数

    $skip 在聚合管道中跳过指定数量的文档,并返回余下的文档

    $unwind 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值

    $group  将集合中的文档分组,可用于统计结果

    $sort  将输入文档排序后输出 

 

   demo1 :  group 分组,统计每个名字出现的次数,大于2次的

复制代码
  pipeline := `[
     "$group": { "_id": "$name", "numTimes": { "$sum": 1 } }},
{"$match" : {"numTimes" : {"$gt" : 2}}}
  ]`

opt := options.Aggregate()
cursor ,err := collection.Aggregate(context.TODO(),MongoPipeline(pipeline),opt)
if err != nil {
log.Fatal(err)
}
var results []bson.M
if err = cursor.All(context.TODO(), &results); err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Printf(
"name %v appears %v times\n",
result["_id"],
result["numTimes"])
}


}

func MongoPipeline(str string) mongo.Pipeline {
var pipeline = []bson.D{}
str = strings.TrimSpace(str)
if strings.Index(str, "[") != 0 {
var doc bson.D
bson.UnmarshalExtJSON([]byte(str), false, &doc)
pipeline = append(pipeline, doc)
} else {
bson.UnmarshalExtJSON([]byte(str), false, &pipeline)
}
return pipeline
}
复制代码

  demo2 :  或者 

复制代码
    pipelint := mongo.Pipeline{
        {{Key : "$group", Value : bson.D{ {Key : "_id", Value : "$name"}, {Key : "numTimes", Value: bson.D{{Key: "$sum", Value : 1}}} }}},
        {{Key : "$match", Value : bson.D{{Key : "numTimes", Value: bson.D{{Key : "$gt", Value : 2}}}}}},
    }

    opt := options.Aggregate()
    cursor ,err := collection.Aggregate(context.TODO(),pipelint,opt)
    if err != nil {
        log.Fatal(err)
    }
    var results []bson.M
    if err = cursor.All(context.TODO(), &results); err != nil {
        log.Fatal(err)
    }
    for _, result := range results {
        fmt.Printf(
            "name %v appears %v times\n",
            result["_id"],
            result["numTimes"])
    }
复制代码

  dem03 :对于结构体数组

复制代码
pipeline := `
    [{
        "$match": {
            "favoritesList.book": "Journey to the West"
        }
    }, {
        "$project": {
            "_id": 0,
            "favoritesList": 1
        }
    }, {
        "$unwind": {
            "path": "$favoritesList"
        }
    }, {
        "$match": {
            "favoritesList.book": "Journey to the West"
        }
    }]`
    collection = client.Database(dbName).Collection(collectionFavorites)
    opts := options.Aggregate()
    if cur, err = collection.Aggregate(ctx, MongoPipeline(pipeline), opts); err != nil {
        t.Fatal(err)
    }
    defer cur.Close(ctx)
    total := 0
    for cur.Next(ctx) {
        total++
    }

func MongoPipeline(str string) mongo.Pipeline {
var pipeline = []bson.D{}
str = strings.TrimSpace(str)
if strings.Index(str, "[") != 0 {
var doc bson.D
bson.UnmarshalExtJSON([]byte(str), false, &doc)
pipeline = append(pipeline, doc)
} else {
bson.UnmarshalExtJSON([]byte(str), false, &pipeline)
}
return pipeline
}
 
复制代码

  demo4 : reduce的写法

复制代码
pipeline := `[
      {
        "$match": {
          "favoritesList.book": "Journey to the West"
        }
      }, {
        "$project": {
          "_id": 0,
          "favoritesList": 1
        }
      }, {
        "$redact": {
          "$cond": {
            "if": {
              "$or": [
                {
                  "$eq": ["$book", "Journey to the West"]
                }, {
                  "$not": "$book"
                }
              ]
            },
            "then": "$$DESCEND",
            "else": "$$PRUNE"
          }
        }
      }, {
        "$unwind": {
          "path": "$favoritesList"
        }
      }
    ]`





pipeline := `[
{
"$match": {
"favoritesList.book": "Journey to the West"
}
}, {
"$project": {
"favoritesList": {
"$filter": {
"input": "$favoritesList",
"as": "favorite",
"cond": {
"$eq": ["$$favorite.book", "Journey to the West"]
}
}
},
"_id": 0
}
}, {
"$unwind": {
"path": "$favoritesList"
}
}
]`
 
复制代码

  dem5 : lookup

复制代码
pipeline := `
    [{
        "$group": {
            "_id": {
                "dealer": "$dealer",
                "style": "$style"
            },
            "brand": {
                "$addToSet": "$brand"
            },
            "count": {
                "$sum": 1
            }
        }
    }, {
        "$lookup": {
            "as": "dealer",
            "from": "dealers",
            "let": {
                "dealerId": "$_id.dealer"
            },
            "pipeline": [{
                "$match": {
                    "$expr": {
                        "$eq": [
                            "$_id", "$$dealerId"
                        ]
                    }
                }
            }, {
                "$project": {
                    "_id": 0,
                    "name": 1
                }
            }]
        }
    }]`
复制代码

  demo6: group

复制代码
    pipeline := `
    [{
        "$group": {
            "_id": "$style",
            "brand": {
                "$addToSet": "$brand"
            },
            "count": {
                "$sum": 1
            }
        }
    }]`
复制代码

  demo7 : 数组

复制代码
pipeline := `
    [{
        "$match": {
            "favoritesList": {
                "$elemMatch": {
                    "city": "London",
                    "book": "Journey to the West"
                }
            }
        }
    }, {
        "$project": {
            "favoritesList": {
                "$filter": {
                    "input": "$favoritesList",
                    "as": "favorite",
                    "cond": {
                        "$eq": ["$$favorite.book", "Journey to the West"]
                    }
                }
            },
            "_id": 0,
            "email": 1
        }
    }, {
        "$unwind": {
            "path": "$favoritesList"
        }
    }]`
复制代码

 

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

  

posted @   dogRuning  阅读(597)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示