mongoDB基本操作
mongoDB基本操作
插入操作
mongo本身的插入方式就非常简单,insert或者batchinsert(批量插入).插入的规则是不允许出现重复的_id元素.
如果在批量插入的时候出现重复的那么在该元素后面的元素都会插入失败.
删除操作
mongo的删除分两种,一种是remove(selector),另一种是drop().remove是移除符合条件的所有项.另一个drop是
删除整个表.在drop的速度会非常快.
更新操作
更新操作其实是需要一些考虑的,因为要考虑到并发问题.mongo的处理方式就是哪个请求先到服务器先处理哪个.跟之前提到
的插入一样,如果_id元素重复的话会发生更新失败,如果批量更新的话会导致后面的更新都失败.这就会造成很大影响.
更新操作的函数是update(selector),会将更新信息写入第一个符合条件的文档.
在go的mgo驱动中直接用Update(selector,newone)的效果是替换,也就是说用新的变量newone替换原来存储在文档中
的内容.
修改器操作
更新操作通常只是更改文档的某一个元素而已,所以没有必要全部替换.mongo提供了原子性的更新修改器.
- $inc 对于数字类型变量可以很方便的做数值修改.例如:{"$inc":{"doc":1}},其中"doc"是文档中数字类型变量(int,float)键.如果没有这个
键值对的话则会新建一个. - $set 可以通过set来修改或者新添一段键值.例如:{"$set":{"testkey":"testvalue"}}.具体的流程我们还是借用
mgo的函数来具体说明一下.collection.Update(bson.M{"test":"test"},{"$set":{"testkey":"testvalue"}}),
Update会找到可以匹配{"test":"test"}这个元素的文档,然后在这些文档中执行$set操作,即是寻找"testkey"这个键,将
值替换为"testvalue".如果没找到这个键的话则新建键值对插入到文档中. - $unset 是$set的逆函数,$unset的参数和流程和$set完全一样,只不过把修改键值队变成了删除键值对,这个修改器需要注意的
是要删除的元素只要键匹配上了就会被删除,而值就算不匹配也会执行操作
数组修改器
在mongo中必然会出现很多一个键对应着一个数组的情况,那么每次都要整体更新的话未免有些浪费性能.所以数组修改器也是非常重要的.
-
$push 向数组中添加元素,如果没有的话就创建一个.通过键来进行索引,将该元素插入至键对应的数组当中.
-
$each 配合着$push使用更佳(笑).举个例子:{"$push":{"$each":["test1","test2","test3"]}}
可以看到,$each就相当于在$push的环境下用$each对数组进行迭代. -
$slice $slice在$push中是用来限制数组长度,举个例子:{"$push":{"$each":["test1","test2","test3"],$slice:-10}}
在这里我们限制了$push数组的长度,-10是用来表示我们会保留最后十个元素.那么正数则代表着从前面开始计数. -
$sort 根据某些数据来对数组进行排序.再举个例子:{"$push":{"$each":["test1","test2","test3"],$slice:-10,$sort:{"index":-1}}}
在这里我们根据"index"这个键来进行逆序的排序,然后再保存最后十个元素.最后要提到的是$sort与$slice要和$each配合使用. -
$addToSet $addToSet和$push的用法基本一致,只是$addToSet添加的时候会检查这个值是否存在与数组中,如果不存在的话则会成功
插入,如果存在的话则不会插入,但是也不会返回任何的错误. -
$pop $pop用来弹出某些元素,举个例子:{"$pop":{"key":1}},{"$pop":{"key":-2}}.
第一个例子则会删除"key"对应的数组的第一个值,第二个例子则会删除"key"对应数组的后两个值. -
$pull $pull可以指定要删除的元素.例如:{"$pull":{"testkey":"testvalue"}}
在这个例子中我们会删除"testkey"对应的数组当中的"testvalue",如果有多个,那么它们会被一并删除 -
$定位操作符 首先明确一点,如果直接对某一个对应着数组的键进行查询操作是可以实现的.下面我用go的mgo做个例子
type testhehe struct{
NewTest []string
}
sh := teststruct{[]string{"test1","test2","test3"}}
sh1 := teststruct{}
err = dhu.Insert(sh)
fmt.Println(err)
err = dhu.Find(bson.M{"newtest":"test2"}).One(&sh1)
fmt.Println(err)
fmt.Println(sh1)
我们直接对newtest这个键查询,目标是存在于数组中的一个元素.结果sh1正确的返回了结果.
假如我们要直接对数组中的这个值进行更改,那么我们还需要知道这个值的位置.而mongo提供了"$"作为定位操作符,下面我还是
贴一段mgo的代码
err = dhu.Update(bson.M{"newtest":"test2"},bson.M{"$set":bson.M{"newtest.$":"test5"}})
在$set中我们使用了"newtest.$"来代表我们在Update中第一个参数传入的查询值所在的位置.这样我们能很方便的修改数组中的某一个
值.
upsert操作
upsert是一个非常好用的操作,好用到我把它单独拿出来.虽然它的内容基本就是insert和update的集合体,但是它是原子性的.
upsert中接受两个参数,如果第一个参数我们匹配到了,那么upsert的效果就等同于update,如果没有匹配到,那么就把第一个参数和第二个
参数合并在一起,然后执行insert操作.
在这里还有一个修改器可以一起用,$setOnInsert.这个修改器的作用是将其对应的键值设置为只插入时生效,更新的时候$setOnInsert对应
的内容是不产生效果的.
下一篇会讲讲mongoDB在go的驱动mgo的写入安全机制,也会稍微介绍一点mongo自己本身的写入安全.