当前位置:网站首页>Use the official go Library of mongodb to operate the original mongodb
Use the official go Library of mongodb to operate the original mongodb
2022-06-12 17:37:00 【Erya preaches Buddhism】
The official database is updated in a timely manner , Best compatibility , The official documents are also relatively complete , The community is more active , Therefore, it is recommended to use this library for interaction .
- GitHub Address (opens new window)
- Official documents (opens new window)
- Community BBS (opens new window)
- Articles on the Internet :
Initialize connection
The initialization method is as follows :
package public
import (
"context"
"log"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func InitDb() *mongo.Client {
uri := "mongodb://root:[email protected]:27017"
if uri == "" {
log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/#environment-variable")
}
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer func() {
if err := client.Disconnect(context.TODO()); err != nil {
panic(err)
}
}()
return client
}A client object is returned here , Then specify the library and table through the method inside .
Specify the library :
var DB *mongo.Database
DB = public.InitDb().Database("class") // Specify the library name as class Designated table :
table := DB.Collection("user") // Specify the table name as userInsert
Insert a single bar
The first example provides a complete example , Only methods are provided later .
package main
import (
"context"
"learn-mongo/public"
"go.mongodb.org/mongo-driver/mongo"
)
var DB *mongo.Database
var ctx = context.Background()
func init() {
// Initialize database
DB = public.InitDb().Database("class")
}
// AddOne Insert a single bar
func AddOne() {
coll := DB.Collection("testdata")
doc := make(map[string]interface{})
doc["title"] = "test"
doc["content"] = "this is a test"
_, err := coll.InsertOne(ctx, doc)
if err != nil {
panic(err)
}
}
func main() {
AddOne()
defer func() {
if err := public.InitDb().Disconnect(context.TODO()); err != nil {
panic(err)
}
}()
}Some of them have been explained , I won't go into details for the time being , After running , You can see this data in the table :
db.getCollection('testdata').find({"title":"test"})
/* 1 */
{
"_id" : ObjectId("61f2389ca0cd2ab482132e57"),
"title" : "test",
"content" : "this is a test"
}Insert more than one
// AddMore Insert more than one
func AddMore() {
coll := DB.Collection("testdata")
docs := []interface{}{
bson.D{{"title", "Record of a Shriveled Datum"}, {"text", "No bytes, no problem. Just insert a document, in MongoDB"}},
bson.D{{"title", "Showcasing a Blossoming Binary"}, {"text", "Binary data, safely stored with GridFS. Bucket the data"}},
}
_, err := coll.InsertMany(context.TODO(), docs)
if err != nil {
panic(err)
}
}to update
Update the list
// UpdateOne Update the list
func UpdateOne() {
coll := DB.Collection("testdata")
filter := bson.D{{"title", "test"}}
update := bson.D{{"$set", bson.D{{"avg_rating", 4.5}}}}
_, err := coll.UpdateOne(context.TODO(), filter, update)
if err != nil {
panic(err)
}
}UpdateOne There are three parameters , Pass a context, A filter rule gets the matching data , One update Indicates the content to be updated .
Here means at testdata In the table title by test This data of , Add a... To the matching record avg_rating Field of , Its value is 4.5.
Update multiple
Before the operation , Let's prepare some test data first :
db.testdata.insert([
{ "name" : " Small A", "identify": "aaa","age": 1, "group_identify": "ops"},
{ "name" : " Small B", "identify": "bbb","age": 2, "group_identify": "ops"},
{ "name" : " Small C", "identify": "ccc","age": 3, "group_identify": "ops"},
{ "name" : " Small D", "identify": "ddd","age": 4, "group_identify": "test"},
{ "name" : " Small E", "identify": "eee","age": 5, "group_identify": "test"},
{ "name" : " Small F", "identify": "fff","age": 6, "group_identify": "test"}
])My need is to update test The age of the group students is current 3 times :
// UpdateMany Update multiple
func UpdateMany() {
coll := DB.Collection("testdata")
filter := bson.D{{"group_identify", "test"}}
update := bson.D{{"$mul", bson.D{{"age", 3}}}}
_, err := coll.UpdateMany(context.TODO(), filter, update)
if err != nil {
panic(err)
}
}MongoDB At the time of the update , Provides some useful methods for us to query , Details refer to :[[MongoDB When interacting, expressions and methods are sorted and summarized #MongoDB Some expressions when updating in ]]
After running this method , You can see that the ages of these three people have been updated :
$ db.getCollection('testdata').find({"group_identify":"test"})
/* 1 */
{
"_id" : ObjectId("61f24699c8d32bc297dbecf2"),
"name" : " Small D",
"identify" : "ddd",
"age" : 12.0,
"group_identify" : "test"
}
/* 2 */
{
"_id" : ObjectId("61f24699c8d32bc297dbecf3"),
"name" : " Small E",
"identify" : "eee",
"age" : 15.0,
"group_identify" : "test"
}
/* 3 */
{
"_id" : ObjectId("61f24699c8d32bc297dbecf4"),
"name" : " Small F",
"identify" : "fff",
"age" : 18.0,
"group_identify" : "test"
}Inquire about
Check the list
// FindOne Check the list
func FindOnd() {
var result bson.M
table := DB.Collection("testdata")
err := table.FindOne(context.TODO(), bson.M{"title": "test"}).Decode(&result) //
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Printf("%v\n", result)
v, err := encoder.Encode(result, encoder.SortMapKeys)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Println(string(v))
}utilize ID Inquire about
// FindOndAsId be based on ID Check the list
func FindOndAsId() {
var result bson.M
table := DB.Collection("user")
objid, err := primitive.ObjectIDFromHex("61f0f6d6c8d32bc297dbecd6")
if err != nil {
fmt.Printf("obj id failed: %v\n", err)
}
err = table.FindOne(context.TODO(), bson.M{"_id": objid}).Decode(&result)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Printf("%v\n", result)
v, err := encoder.Encode(result, encoder.SortMapKeys)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Println(string(v))
}Fuzzy query
type Article struct {
Title string
Text string
}
// FindAsLike Fuzzy query
func FindAsLike() {
table := DB.Collection("testdata")
findOptions := options.Find()
filter := bson.D{}
filter = append(filter, bson.E{
Key: "title",
Value: bson.M{"$regex": primitive.Regex{Pattern: ".*" + "a" + ".*", Options: "i"}}}) //i Indicates case insensitive
cus, err := table.Find(ctx, filter, findOptions)
if err != nil {
fmt.Printf("find failed: %v\n", err)
}
defer func(cus *mongo.Cursor, ctx context.Context) {
err := cus.Close(ctx)
if err != nil {
return
}
}(cus, ctx)
list := make([]*Article, 0)
for cus.Next(ctx) {
article := new(Article)
err := cus.Decode(&article)
if err != nil {
fmt.Printf("decode failed: %v\n", err)
// return nil, tools.NewMongoError(err)
}
list = append(list, article)
}
fmt.Println("results: ", list)
for _, v := range list {
fmt.Println(v)
}
}Query multiple
// FindMany Query multiple
func FindMany() {
/*
Insert test data
db.testdata.insert([
{ "name" : " Small A", "identify": "aaa","age":1},
{ "name" : " Small B", "identify": "bbb","age":2},
{ "name" : " Small C", "identify": "ccc","age":3},
{ "name" : " Small D", "identify": "ddd","age":4},
{ "name" : " Small E", "identify": "eee","age":5},
{ "name" : " Small F", "identify": "fff","age":6},
])
*/
table := DB.Collection("testdata")
filter := bson.D{{"age", bson.D{{"$lte", 3}}}} // Query age is less than or equal to 3 Of , It's very interesting here , Able to use $lte This method , Something like that ,MongoDB Many other query methods are also provided , such as $gt wait
cursor, err := table.Find(ctx, filter)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
var results []bson.M
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
v, err := encoder.Encode(result, encoder.SortMapKeys)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Println(string(v))
}
}Just like when updating , There are also some expressions available for query . More reference :[[MongoDB When interacting, expressions and methods are sorted and summarized #mongodb The expression of query in ]]
Replace
Replace single
ReplaceOne() You can use this method to replace documents in the collection . This method is aimed at cmdb The scene is more appropriate .
First, add a piece of test data :
db.testdata.insert([
{ "name" : " Small A", "identify": "aaa","content":"this is aaa"},
])Then based on identify Completely replace This record :
// ReplaceOne Replace single
func ReplaceOne() {
coll := DB.Collection("testdata")
filter := bson.D{{"identify", "aaa"}}
replacement := bson.D{{"name", " Small A-r"}, {"identify", "aaa"}, {"content", "this is aaa replace"}}
_, err := coll.ReplaceOne(context.TODO(), filter, replacement)
if err != nil {
panic(err)
}
}Delete
To delete a single
// DeleteOne To delete a single
func DeleteOne() {
coll := DB.Collection("testdata")
filter := bson.D{{"identify", "aaa"}}
_, err := coll.DeleteOne(context.TODO(), filter)
if err != nil {
panic(err)
}
}Delete multiple
Again , When deleting , We call Delete Method , Pass filter conditions , At this time, you can also delete the specified filter conditions .
Add test data :
db.testdata.insert([
{ "name" : " Small A", "identify": "aaa","age": 1, "group_identify": "ops"},
{ "name" : " Small B", "identify": "bbb","age": 2, "group_identify": "ops"},
{ "name" : " Small C", "identify": "ccc","age": 3, "group_identify": "ops"},
{ "name" : " Small D", "identify": "ddd","age": 4, "group_identify": "test"},
{ "name" : " Small E", "identify": "eee","age": 5, "group_identify": "test"},
{ "name" : " Small F", "identify": "fff","age": 6, "group_identify": "test"}
])We delete older than 3 Years old record :
// DeleteMany Delete multiple
func DeleteMany() {
coll := DB.Collection("testdata")
filter := bson.D{{"age", bson.D{{"$gt", 3}}}}
_, err := coll.DeleteMany(context.TODO(), filter)
if err != nil {
panic(err)
}
}Then you can see that only the first three are left :
$ db.getCollection('testdata').find({})
/* 1 */
{
"_id" : ObjectId("61f24a4dc8d32bc297dbed02"),
"name" : " Small A",
"identify" : "aaa",
"age" : 1.0,
"group_identify" : "ops"
}
/* 2 */
{
"_id" : ObjectId("61f24a4dc8d32bc297dbed03"),
"name" : " Small B",
"identify" : "bbb",
"age" : 2.0,
"group_identify" : "ops"
}
/* 3 */
{
"_id" : ObjectId("61f24a4dc8d32bc297dbed04"),
"name" : " Small C",
"identify" : "ccc",
"age" : 3.0,
"group_identify" : "ops"
}Batch
BulkWrite() You can use this method to perform a batch write operation on the collection .
The official example is as follows :
coll := DB.Collection("testdata")
models := []mongo.WriteModel{
mongo.NewReplaceOneModel().SetFilter(bson.D{{"title", "Record of a Shriveled Datum"}}).
SetReplacement(bson.D{{"title", "Dodging Greys"}, {"text", "When there're no matches, no longer need to panic. You can use upsert"}}),
mongo.NewUpdateOneModel().SetFilter(bson.D{{"title", "Dodging Greys"}}).
SetUpdate(bson.D{{"$set", bson.D{{"title", "Dodge The Greys"}}}}),
}
opts := options.BulkWrite().SetOrdered(true)
results, err := coll.BulkWrite(context.TODO(), models, opts)- Match a document , among
titleyes “ Record of shrinkage datum ” And replace it with a new document - Match among them
titleby “Dodging Greys” And update the value to 'Dodge The Greys'
This kind of batch method is seldom used .
Summary
Two ways
EstimatedDocumentCount(): Get an approximation of the number of documents in the collectionCountDocuments(): Get the exact number of documents in the collection
// Count Query quantity
func Count() {
coll := DB.Collection("testdata")
filter := bson.D{{"group_identify", "test"}}
estCount, estCountErr := coll.EstimatedDocumentCount(context.TODO())
if estCountErr != nil {
panic(estCountErr)
}
count, err := coll.CountDocuments(context.TODO(), filter)
if err != nil {
panic(err)
}
fmt.Println(estCount, count)
}relation
Relational query
be based on MongoDB Reference to the query operation flow of the original statement :[[MongoDB The study and practice of association query ]]
Now? golang The following methods are used to implement Association query in :
func Aggregate() {
query := []bson.M{{
"$lookup": bson.M{
"from": "user",
"localField": "identify",
"foreignField": "groupIdentify",
"as": "output",
}}}
coll := DB.Collection("group")
cur, err := coll.Aggregate(context.TODO(), query)
if err != nil {
fmt.Printf("aggregate failed:%v\n", err)
}
defer cur.Close(context.TODO())
for cur.Next(context.TODO()) {
// When the data is not mapped to the structure , Can pass map Inquire about
one := make(map[string]interface{})
err := cur.Decode(&one)
if err != nil {
fmt.Printf("%v\n", err)
}
v, err := encoder.Encode(one, encoder.SortMapKeys)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Println(string(v))
}
}The operation results are as follows :
$ go run main.go | jq
{
"_id": "61f0f6c2c8d32bc297dbecd2",
"identify": "yunweizu",
"name": " Operation and maintenance group ",
"output": [
{
"_id": "61f0f6d6c8d32bc297dbecd4",
"groupIdentify": "yunweizu",
"identify": "aaa",
"name": " Small A"
},
{
"_id": "61f0f6d6c8d32bc297dbecd5",
"groupIdentify": "yunweizu",
"identify": "bbb",
"name": " Small B"
},
{
"_id": "61f0f6d6c8d32bc297dbecd6",
"groupIdentify": "yunweizu",
"identify": "ccc",
"name": " Small C"
}
]
}
{
"_id": "61f0f6c2c8d32bc297dbecd3",
"identify": "kefuzu",
"name": " Customer service group ",
"output": [
{
"_id": "61f0f6d6c8d32bc297dbecd7",
"groupIdentify": "kefuzu",
"identify": "ddd",
"name": " Small D"
},
{
"_id": "61f0f6d6c8d32bc297dbecd8",
"groupIdentify": "kefuzu",
"identify": "eee",
"name": " Small E"
},
{
"_id": "61f0f6d6c8d32bc297dbecd9",
"groupIdentify": "kefuzu",
"identify": "fff",
"name": " Small F"
}
]
}If you want to filter the specified groups , Use the following method :
func Aggregate() {
query := []bson.M{{
"$lookup": bson.M{
"from": "user",
"localField": "identify",
"foreignField": "groupIdentify",
"as": "output",
}},
{"$match": bson.M{"identify": "yunweizu"}},
}
coll := DB.Collection("group")
cur, err := coll.Aggregate(context.TODO(), query)
if err != nil {
fmt.Printf("aggregate failed:%v\n", err)
}
defer cur.Close(context.TODO())
for cur.Next(context.TODO()) {
// When the data is not mapped to the structure , Can pass map Inquire about
one := make(map[string]interface{})
err := cur.Decode(&one)
if err != nil {
fmt.Printf("%v\n", err)
}
v, err := encoder.Encode(one, encoder.SortMapKeys)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Println(string(v))
}
}The operation results are as follows :
$ go run main.go | jq
{
"_id": "61f0f6c2c8d32bc297dbecd2",
"identify": "yunweizu",
"name": " Operation and maintenance group ",
"output": [
{
"_id": "61f0f6d6c8d32bc297dbecd4",
"groupIdentify": "yunweizu",
"identify": "aaa",
"name": " Small A"
},
{
"_id": "61f0f6d6c8d32bc297dbecd5",
"groupIdentify": "yunweizu",
"identify": "bbb",
"name": " Small B"
},
{
"_id": "61f0f6d6c8d32bc297dbecd6",
"groupIdentify": "yunweizu",
"identify": "ccc",
"name": " Small C"
}
]
}It's basically like writing native statements .
Field
Add fields
Add a single
A single field uses $push Command to add :
// UpdateOneField Add a single field
func UpdateOneField() {
coll := DB.Collection("testdata")
objid, err := primitive.ObjectIDFromHex("62159551120b25bd2c801b09")
if err != nil {
fmt.Printf("%v\n", err)
}
filter := bson.M{"_id": objid}
updata := bson.M{"$push": bson.M{"link_data": bson.M{"field_identify": "1", "model_data_id": "5"}}}
_, err = coll.UpdateOne(ctx, filter, updata)
if err != nil {
panic(err)
}
}The effect after adding is as follows :
/* 1 */
{
"_id" : ObjectId("62159551120b25bd2c801b09"),
"title" : "Record of a Shriveled Datum",
"text" : "No bytes, no problem. Just insert a document, in MongoDB",
"link_data" : [
{
"field_identify" : "1",
"model_data_id" : "5"
},
}
]
} Pay attention to the use of $push One problem is , If a value is repeatedly added to an array , So in MongoDB Will be added repeatedly in , The effect is as follows :
$ db.getCollection('test').find({})
/* 1 */
{
"_id" : ObjectId("61ef6e9d78a349e08e8f50da"),
"test" : "test"
}
$ db.test.update({ "test" : "test" },{ $push: { label_list: "1" } })
Run again
$ db.test.update({ "test" : "test" },{ $push: { label_list: "1" } })
Then the query
$ db.getCollection('test').find({})
/* 1 */
{
"_id" : ObjectId("61ef6e9d78a349e08e8f50da"),
"test" : "test",
"label_list" : [
"1",
"1"
]
}In this case, you can use addToSet, Efficacy and push Agreement , It's just
$ db.getCollection('test').find({})
/* 1 */
{
"_id" : ObjectId("61ef6e9d78a349e08e8f50da"),
"test" : "test"
}
$ db.test.update({ "test" : "test" },{ $addToSet: { label_list: "1" } })
Run again
$ db.test.update({ "test" : "test" },{ $addToSet: { label_list: "1" } })
Then the query
$ db.getCollection('test').find({})
/* 1 */
{
"_id" : ObjectId("61ef6e9d78a349e08e8f50da"),
"test" : "test",
"label_list" : [
"1"
]
}As you can see, although it has been executed twice , But the data will only be inserted once , It is suitable for the scenario of one-time Association .
Add more than one
Multiple fields utilize push and each Add by combining ,each Allow us to add the contents of an array :
// UpdateOneField Add single field data
func UpdateOneField() {
coll := DB.Collection("testdata")
objid, err := primitive.ObjectIDFromHex("62159551120b25bd2c801b09")
if err != nil {
fmt.Printf("%v\n", err)
}
filter := bson.M{"_id": objid}
linkData := []map[string]string{
{
"field_identify": "eryajf_guanliandd",
"model_data_id": "6215aaf220ea934fb727096c",
},
{
"field_identify": "eryajf_guanliandd",
"model_data_id": "6215aaf220ea934fbaaaaaaa",
},
}
updata := bson.M{"$push": bson.M{"link_data": bson.M{"$each": linkData, "$position": 0}}}
_, err = coll.UpdateOne(ctx, filter, updata)
if err != nil {
panic(err)
}
}The effect after adding is as follows :
/* 1 */
{
"_id" : ObjectId("62159551120b25bd2c801b09"),
"title" : "Record of a Shriveled Datum",
"text" : "No bytes, no problem. Just insert a document, in MongoDB",
"link_data" : [
{
"field_identify" : "eryajf_guanliandd",
"model_data_id" : "6215aaf220ea934fb727096c"
},
{
"field_identify" : "eryajf_guanliandd",
"model_data_id" : "6215aaf220ea934fbaaaaaaa"
}
]
}Again , Use here push There is a problem , The same data , When adding multiple times , Will be stored many times , So here we can use addToSet The ability of , Realize the effect of automatic weight removal .
About push And addToSet Similarities and differences , For details, please refer to this article :golang Use push and addToSet The similarities and differences of adding fields to an array (opens new window)
Delete field
To delete a single
A single field uses $pull Instruction to delete :
// DeleteOneField Delete single field data
func DeleteOneField() {
coll := DB.Collection("testdata")
objid, err := primitive.ObjectIDFromHex("62159551120b25bd2c801b09")
if err != nil {
fmt.Printf("%v\n", err)
}
filter := bson.M{"_id": objid}
updata := bson.M{"$pull": bson.M{"link_data": bson.M{"field_identify": "1", "model_data_id": "5"}}}
_, err = coll.UpdateOne(ctx, filter, updata)
if err != nil {
panic(err)
}
}Delete multiple
Delete multiple records using $pullAll Instruction to delete :
// DeleteManyField Delete multiple records
func DeleteManyField() {
coll := DB.Collection("testdata")
objid, err := primitive.ObjectIDFromHex("62159551120b25bd2c801b09")
if err != nil {
fmt.Printf("%v\n", err)
}
filter := bson.M{"_id": objid}
linkData := []map[string]string{
{
"field_identify": "eryajf_guanliandd",
"model_data_id": "6215aaf220ea934fb727096c",
},
{
"field_identify": "eryajf_guanliandd",
"model_data_id": "6215aaf220ea934fbaaaaaaa",
},
}
updata := bson.M{"$pullAll": bson.M{"link_data_testa": linkData}}
_, err = coll.UpdateOne(ctx, filter, updata)
if err != nil {
panic(err)
}
}边栏推荐
- Detailed explanation of shardingjdbc database and table
- R语言使用epiDisplay包的tableStack函数基于分组变量生成统计分析表(包含描述性统计分析、假设检验、不同数据使用不同的统计量和假设检验方法)、自定义配置是否显示统计检验内容
- Codeforces Round #398 (Div. 2) D. Cartons of milk
- How to change Golan back to the English version when it becomes the Chinese version
- Two ways of tensorflow2 training data sets
- [CSP]202012-2期末预测之最佳阈值
- R语言使用epiDisplay包的aggregate.plot函数可视化每个子集的汇总统计信息(可视化基于单个分组下的阳性指标的概率值及其95%置信区间、基于折线图、仅仅适用于目标类别为二分类)
- ShardingJDBC 分库分表详解
- Understanding of binary search
- Analysis of CA certificate with high value
猜你喜欢

布局管理中的sizePolicy的策略问题

进阶之大山-asp.net core 路由程序基础使用演示0.1

字节飞书人力资源套件三面

How to win the "Olympic Games" in retail technology for jd.com, the learning tyrant of the "regular examination"?
Memory control of node

Arm64栈回溯

Article name

Compilation optimization of performance optimization

I heard that distributed IDS cannot be incremented globally?

龙芯处理器内核中断讲解
随机推荐
Add static route
[CSP]202012-2期末预测之最佳阈值
73. 矩阵置零(标记法)
R language uses the sum function of epidisplay package to calculate the descriptive statistical summary information of the specified variables in dataframe under different grouped variables and visual
SqlServer常用语句及函数
R语言使用epiDisplay包的pyramid函数可视化金字塔图、基于已有的汇总数据(表格数据)可视化金字塔图
消息队列存储消息数据的 MySQL 表格
118. 杨辉三角(动态规划)
R语言使用epiDisplay包的tabpct函数生成二维列联表并使用马赛克图可视化列联表(二维列联表、边际频数、以及按行、按列的比例)、自定义设置ylab参数设置Y轴的轴标签文本(y axis)
Project training of Software College of Shandong University - Innovation Training - network attack and defense shooting range experimental platform of Software College of Shandong University (XXV) - p
Li Kou today's question 926 Flip string to monotonic increment
406. 根据身高重建队列
论文《Deep Interest Evolution Network for Click-Through Rate Prediction》
Use GCC's PGO (profile guided optimization) to optimize the entire system
String s = null ; String s = new String();String s =““ ;String s ;有什么区别?
Evolution and thinking of Taobao native R & D mode | DX R & D mode
Some minor problems and solutions encountered when using ubantu
Nebula's practice of intelligent risk control in akulaku: training and deployment of graph model
First acquaintance with go language
内核中断整体流程图