Go 在 MongoDB 中常用查询与修改的操作
程序员文章站
2022-03-07 12:45:42
以下所有例子中结构定义如下:type user struct { id_ bson.objectid `bson:"_id"` name string `bson:"name"` a...
以下所有例子中结构定义如下:
type user struct { id_ bson.objectid `bson:"_id"` name string `bson:"name"` age int `bson:"age"` joinedat time.time `bson:"joined_at"` interests []string `bson:"interests"` num []int `bson:"num"` }
1、查询
通过func (c *collection) find(query interface{}) *query来进行查询,返回的query struct可以有附加各种条件来进行过滤。
通过query.all()可以获得所有结果,通过query.one()可以获得一个结果,注意如果没有数据或者数量超过一个,one()会报错。
条件用bson.m{key: value},注意key必须用mongodb中的字段名,而不是struct的字段名。
1.1、查询所有
var users []user c.find(nil).all(&users)
上面代码可以把所有users都查出来:
1.2、根据objectid查询
id := "5204af979955496907000001" objectid := bson.objectidhex(id) user := new(user) c.find(bson.m{"_id": objectid}).one(&user)
更简单的方式是直接用findid()方法:
c.findid(objectid).one(&user)
注意这里没有处理err。当找不到的时候用one()方法会出错。
1.3、单条件查询
=($eq) c.find(bson.m{"name": "jimmy kuu"}).all(&users) !=($ne) c.find(bson.m{"name": bson.m{"$ne": "jimmy kuu"}}).all(&users) >($gt) c.find(bson.m{"age": bson.m{"$gt": 32}}).all(&users) <($lt) c.find(bson.m{"age": bson.m{"$lt": 32}}).all(&users) >=($gte) c.find(bson.m{"age": bson.m{"$gte": 33}}).all(&users) <=($lte) c.find(bson.m{"age": bson.m{"$lte": 31}}).all(&users) in($in) c.find(bson.m{"name": bson.m{"$in": []string{"jimmy kuu", "tracy yu"}}}).all(&users)
1.4、多条件查询
and($and) c.find(bson.m{"name": "jimmy kuu", "age": 33}).all(&users) or($or) c.find(bson.m{"$or": []bson.m{bson.m{"name": "jimmy kuu"}, bson.m{"age": 31}}}).all(&users)
2、修改
通过func (*collection) update来进行修改操作。
func (c *collection) update(selector interface{}, change interface{}) error
注意修改单个或多个字段需要通过$set操作符号,否则集合会被替换。
2.1、($set)
//修改字段的值 c.update( bson.m{"_id": bson.objectidhex("5204af979955496907000001")}, bson.m{"$set": bson.m{ "name": "jimmy gu", "age": 34 }} )
2.2、inc($inc)
//字段增加值 c.update( bson.m{"_id": bson.objectidhex("5204af979955496907000001")}, bson.m{"$inc": bson.m{ "age": -1 }} ) //字段num数组第三个数增加值 c.update( bson.m{"_id": bson.objectidhex("5204af979955496907000001")}, bson.m{"$inc": bson.m{ "num." + strconv.itoa(2): 1 }})
2.3、push($push)
//从数组中增加一个元素 c.update( bson.m{"_id": bson.objectidhex("5204af979955496907000001")}, bson.m{"$push": bson.m{ "interests": "golang" }} )
2.4、pull($pull)
//从数组中删除一个元素 c.update( bson.m{"_id": bson.objectidhex("5204af979955496907000001")}, bson.m{"$pull": bson.m{ "interests": "golang" }} )
2.5、删除
c.remove(bson.m{"name": "jimmy kuu"})
补充:golang mongodb查找find demo
使用gopkg.in/mgo.v2库操作,插入操作主要使用mongodb中collection对象的find方法,函数原型:
func (c *collection) find(query interface{}) *query
查找的时候find的参数都会用bson.m类型
type m map[string]interface{}
例如:bson.m{"name": "tom"}相当直接mongodb的查询条件{"name": "tom"}
统一封装下getdb方法
package main import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) // get mongodb db func getdb() *mgo.database { session, err := mgo.dial( "172.16.27.134:10001" ) if err != nil { panic(err) } session.setmode(mgo.monotonic, true) db := session.db( "test" ) return db }
查找单条记录
func findone() { db := getdb() c := db.c( "user" ) // 用struct接收,一般情况下都会这样处理 type user struct { name string "bson:`name`" age int "bson:`age`" } user := user{} err := c.find(bson.m{ "name" : "tom" }).one(&user) if err != nil { panic(err) } fmt.println(user) // output: {tom 20} // 用bson.m结构接收,当你不了解返回的数据结构格式时,可以用这个先查看,然后再定义struct格式 // 在处理mongodb组合查询时,经常这么干 result := bson.m{} err = c.find(nil).one(&result) if err != nil { panic(err) } fmt.println(result) // output: map[_id:objectidhex("56fdce98189df8759fd61e5b") name:tom age:20] }
查找多条记录
func findmuit() { db := getdb() c := db.c( "user" ) // 使用all方法,一次性消耗较多内存,如果数据较多,可以考虑使用迭代器 type user struct { id bson.objectid `bson: "_id,omitempty" ` name string "bson:`name`" age int "bson:`age`" } var users []user err := c.find(nil).all(&users) if err != nil { panic(err) } fmt.println(users) // output: [{objectidhex("56fdce98189df8759fd61e5b") tom 20}...] // 使用迭代器获取数据可以避免一次占用较大内存 var user user iter := c.find(nil).iter() for iter.next(&user) { fmt.println(user) } // output: // {objectidhex("56fdce98189df8759fd61e5b") tom 20} // {objectidhex("56fdce98189df8759fd61e5c") tom 20} // ... }
查找指定字段
主要使用select函数:
func (q *query) select(selector interface{}) *query
func findfield() { db := getdb() c := db.c( "user" ) // 只读取name字段 type user struct { name string "bson:`name`" } var users []user err := c.find(bson.m{}).select(bson.m{ "name" : 1 }).all(&users) if err != nil { panic(err) } fmt.println(users) // output: [{tom} {tom} {anny}...] // 只排除_id字段 type user2 struct { name string "bson:`name`" age int "bson:`age`" } var users2 []user2 err = c.find(bson.m{}).select(bson.m{ "_id" : 0 }).all(&users2) if err != nil { panic(err) } fmt.println(users2) // output: [{tom 20} {tom 20} {anny 28}...] }
查询嵌套格式数据
func findnesting() { db := getdb() c := db.c( "user" ) // 使用嵌套的struct接收数据 type user struct { name string "bson:`name`" age int "bson:`age`" toys []struct { name string "bson:`name`" } } var users user // 只查询toys字段存在的 err := c.find(bson.m{ "toys" : bson.m{ "$exists" : true}}).one(&users) if err != nil { panic(err) } fmt.println(users) // output: {tom 20 [{dog}]} }
查找数据总数
func count() { db := getdb() c := db.c( "user" ) // 查找表总数 count, err := c.count() if err != nil { panic(err) } fmt.println(count) // output: 8 // 结合find条件查找 count, err = c.find(bson.m{ "name" : "tom" }).count() if err != nil { panic(err) } fmt.println(count) // output: 6 }
对数据进行排序
使用sort函数
func (q *query) sort(fields ...string) *query
func findsort() { db := getdb() c := db.c( "user" ) type user struct { id bson.objectid `bson: "_id,omitempty" ` name string "bson:`name`" age int "bson:`age`" } var users []user // 按照age字段降序排列,如果升序去掉横线"-"就可以了 err := c.find(nil).sort( "-age" ).all(&users) if err != nil { panic(err) } fmt.println(users) // output: // [{objectidhex("56fdce98189df8759fd61e5d") anny 28} ...] // ... }
分页查询
使用skip函数和limit函数
func (q *query) skip(n int) *query func (q *query) limit(n int) *query
func findpage() { db := getdb() c := db.c( "user" ) type user struct { id bson.objectid `bson: "_id,omitempty" ` name string "bson:`name`" age int "bson:`age`" } var users []user // 表示从偏移位置为2的地方开始取两条记录 err := c.find(nil).sort( "-age" ).skip( 2 ).limit( 2 ).all(&users) if err != nil { panic(err) } fmt.println(users) // output: // [{objectidhex("56fdce98189df8759fd61e5d") anny 20} ...] // ... }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。
下一篇: 详解MySQL数据库千万级数据查询和存储