mongodb的修改器
在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整、增加、或者删除键,还可以操作数组和内嵌文档。增加、修改或删除键的时候,应该使用$修改器。要把"foo"的值设备"bar",常见的错误做法如下:
db.coll.update(criteria,{"foo":"bar"})
这种情况是不对的,实际上这种做法会把整个文档用{"foo":"bar"}替换掉,一定要使用以$开头的修改器来修改键/值对。
1. $set修改器
$set 修改器用来指定一个键值。如果这个键不存在,则创建他,他对更新模式或者用户定义键来说非常方便。
> db.users.findOne()
{
"_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
"name" : "joe",
"age" : ,
"sex" : "male",
"location" : "Wisconsin",
"favorite book" : "war and pace"
} > db.users.update({"name":"joe"},{"$set":{"favorite book":["cat's cardle","foundation trilogy","ender's game"]}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
"name" : "joe",
"age" : ,
"sex" : "male",
"location" : "Wisconsin",
"favorite book" : [
"cat's cardle",
"foundation trilogy",
"ender's game"
]
}
2. $set用来修改内嵌文档
> db.blog.insert({"title":"a blog post","author":{"name":"joe","email":"joe@example.com"}})
WriteResult({ "nInserted" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"author" : {
"name" : "joe",
"email" : "joe@example.com"
}
}
> db.blog.update({"author.name":"joe"},{"$set":{"author.name":"joe schmoe"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"author" : {
"name" : "joe schmoe",
"email" : "joe@example.com"
}
}
> db.blog.update({"title":"a blog post"},{"$set":{"author.name":"joe schmoe op"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"author" : {
"name" : "joe schmoe op",
"email" : "joe@example.com"
}
}
>
3. $unset修改器
$unset修改用于将键删除
> db.users.findOne()
{
"_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
"name" : "joe",
"age" : ,
"sex" : "male",
"location" : "Wisconsin",
"favorite book" : [
"cat's cardle",
"foundation trilogy",
"ender's game"
]
}
> db.users.update({"name":"joe"},{"$unset":{"favorite book":}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
"name" : "joe",
"age" : ,
"sex" : "male",
"location" : "Wisconsin"
}
4. $inc修改器
$inc其用来增加或减少已有的键的键值,或者在键不存在的时候创建一个键。
> db.games.insert({"game":"pinball","user":"joe"})
WriteResult({ "nInserted" : })
> db.games.findOne()
{
"_id" : ObjectId("5770a1394f533aa7535d46d4"),
"game" : "pinball",
"user" : "joe"
}
> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.games.findOne()
{
"_id" : ObjectId("5770a1394f533aa7535d46d4"),
"game" : "pinball",
"user" : "joe",
"score" :
}
为"score"键增加50再减少20
> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.games.findOne()
{
"_id" : ObjectId("5770a1394f533aa7535d46d4"),
"game" : "pinball",
"user" : "joe",
"score" :
}
> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":-}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.games.findOne()
{
"_id" : ObjectId("5770a1394f533aa7535d46d4"),
"game" : "pinball",
"user" : "joe",
"score" :
}
以上"$inc"与"$set"的用法类似,就是专门用来增加或减少数字的。"$inc"只能用于整数、长整数或双精度浮点数,要是在其他类型的数据上就会导致操作失败,其中包括很多语言会自动转换成数字的类型,例如null,布尔类型,或数字构成的字符串。"$inc"键的值必须为数字,不能使用字符串、数组和其他非数字的值,否则会报错,要修改其他类型,只能使用"$set"。
如下:
> db.foo.insert({"count":""})
WriteResult({ "nInserted" : })
> db.foo.find()
{ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : "" }
> db.foo.update({},{"$inc":{"count":}})
WriteResult({
"nMatched" : ,
"nUpserted" : ,
"nModified" : ,
"writeError" : {
"code" : ,
"errmsg" : "Cannot apply $inc to a value of non-numeric type. {_id: ObjectId('5770befc4f533aa7535d46d5')} has the field 'count' of non-numeric type String"
}
}) > db.foo.update({},{$set:{count:}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.foo.find()
{ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : }
>
5. 数组修改器 $push
数组修改器,顾名思义它只可以用于操作数组,只能用在值为数组的键上。$push修改器如果指定的值已经存在,"$push"会想已有的数组末尾加入一个元素,要是没有就会创建一个新的数组。
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"author" : {
"name" : "joe schmoe op",
"email" : "joe@example.com"
}
}
> db.blog.update({"title":"a blog post"},{"$unset":{"author":}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post" }
> db.blog.update({"title":"a blog post"},{"$push":{"comments":{"name":"joe","email":"joe@example.com","content":"nice post"}}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
}
]
}
为blog集合"a blog post"文档再增加一条评论:
> db.blog.update({"title":"a blog post"},{"$push":{"comments":{"name":"bob","email":"bob@example.com","content":"good post"}}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post"
}
]
}
6. 数组修改器 $ne
$ne也是用来操作数组的修改器,在查询文档中,如果一个值不在数组里面就把他加进去,如果在不添加。
> db.users.insert({"name":"joe","emails":["joe@example.com","joe@gmail.com","joe@yahoo.com"]})
WriteResult({ "nInserted" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com"
]
}
> db.users.update({"name":"joe","emails":{$ne:"joe@gmail.com"}},{$push:{"emails":"joe@gmail.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : }) --nMatched为0表示没有修改
> db.users.update({"name":"joe","emails":{$ne:"joe@itpub.com"}},{$push:{"emails":"joe@itpub.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com"
]
}
以上这种方式也可以使用$addToSet实现。
7. 数组修改器 $addToSet
$addToSet也是用来操作数组的修改器,实现的功能与$ne修改器相同,且更为方便。使用$addToSet修改器可以避免重复。
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com"
]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":"joe@gmail.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : }) --原文档里已有"joe@gmail.com",修改完也没有产生重复值
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com"
]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":"joe@163.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com"
]
}
8. 数组修改器 $each
$each数组修改器要和$addToSet修改结合起来用,可以一次添加多个不同的值。例如上面的例子中,我们一次添加多个email值, 如下:
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com"
]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{$each:["joe@example.com","joe@python.com","joe@php.com"]}})
WriteResult({
"nMatched" : ,
"nUpserted" : ,
"nModified" : ,
"writeError" : {
"code" : ,
"errmsg" : "The dollar ($) prefixed field '$each' in '$each' is not valid for storage."
}
})
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":{$each:["joe@example.com","joe@python.com","joe@php.com"]}}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com",
"joe@php.com"
]
}
>
9. 数组修改器 $pop
$pop修改器主要于从数组中删除元素,他可以从数组中的任何一端删除元素,
例如:
{$pop:{key:1}} 从数组末尾删除一个元素
{$pop:{key:-1}} 从数组头部删除一个元素
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com",
"joe@php.com"
]
}
> db.users.update({"name":"joe"},{$pop:{"emails":}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com"
]
}
> db.users.update({"name":"joe"},{$pop:{"emails":-}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com"
]
}
有时我们需要基于特定条件来删除元素,而不仅仅依据位置,就可以使用$pull修改器
10. 数组修改器 $pull
$pull修改器和$pop修改类似,都是用来删除数组中的元素
$pull可以基于特定条件来删除元素
$pull会将所有匹配到的数据全部删掉,如对数组[1,2,1,1]执行pull 1,得到的结果就是只有一个元素的数组[2]
例如我们想删除emails数组中的"joe@163.com"和"joe@itpub.com"两个元素:
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com"
]
}
> db.users.update({"name":"joe"},{$pull:{"emails":["joe@163.com","joe@itpub.com"]}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : }) --好像不能一次删除多个,没有起作用
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@gmail.com",
"joe@yahoo.com",
"joe@itpub.com",
"joe@163.com",
"joe@python.com"
]
}
> db.users.update({"name":"joe"},{$pull:{"emails":"joe@163.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.update({"name":"joe"},{$pull:{"emails":"joe@itpub.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.users.findOne()
{
"_id" : ObjectId("5770ca42e90c1adc80040a08"),
"name" : "joe",
"emails" : [
"joe@gmail.com",
"joe@yahoo.com",
"joe@python.com"
]
}
11. 数组的定位修改器 $
若是数组有多个值,而我们只想对其中一部分进行操作,有两种方法可以实现这种操作。
两种方法操作数组中的值:通过位置或定位操作符("$")
数组都是以0开头的,可以将下标直接作为键来选择元素。
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post"
}
]
}
> db.blog.update({"title":"a blog post"},{$set:{"comments.1.name":"livan"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "livan",
"email" : "bob@example.com",
"content" : "good post"
}
]
}
> db.blog.update({"title":"a blog post"},{$set:{"comments.1.email":"livan@example.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "livan",
"email" : "livan@example.com",
"content" : "good post"
}
]
}
在很多情况下,不预先查询文档就不能知道要修改数组的下标,为了克服这种困难,mongodb提供了定位操作符"$",
用来定位查询文档已经匹配的元素,并进行更新,定位符只更新第一个匹配的元素。
例如:用户john把名字改成了jim,就可以用定位符来替换评论中的名字:
db.blog.update({"comments.author":"john"},{$set:{"comments.$.author:"john"}})
可以理解为{"comments.author":"john"}查询条件定位到第一个元素,就执行{$set:{"comments.$.author:"john"}},"$"定位符就表示找到的第一个元素
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "livan",
"email" : "livan@example.com",
"content" : "good post"
}
]
}
> db.blog.update({"comments.name":"livan"},{$set:{"comments.$.email":"bob@example.com"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.update({"comments.name":"livan"},{$set:{"comments.$.name":"bob"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })
> db.blog.findOne()
{
"_id" : ObjectId("57709da84f533aa7535d46d3"),
"title" : "a blog post",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post"
},
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post"
}
]
}
《MongoDB权威指南中文版》
mongdb数组修改 http://blog.163.com/wm_at163/blog/static/1321734902012526111917601/
mongodb的修改器的更多相关文章
- MongoDB之修改器
MongoDB之修改器 $set 简单粗暴 {name: valuel} 直接将key对应的值赋值给value. db.xxoo.insert({}, {set: {key: value}}) / ...
- MongoDB update修改器 目录
MongoDB update修改器: 针对Fields的$修改器 $inc $set $unset MongoDB update修改器: 针对Arrays的$修改器 $push $pull $pop ...
- MongoDB update修改器: 针对Fields的$修改器 $inc $set $unset
MongoDB update修改器: $inc $set $unset $push $pull $pop 针对Fields的$修改器 $set: { $set: { key: value } } $s ...
- MongoDB数组修改器更新数据(转)
MongoDB数组修改器更新数据 这里,我们将了解一下数组修改器.数组,是我们经常看到和使用到的且非常有用的数据结构:它不仅可以通过索进行引用,还可以作为集合来使用.数组修改器,顾名思义,它是用 ...
- MongoDB update修改器: 针对Arrays的$修改器 $push $pull $pop
针对Arrays的$修改器 $push : { $push: { key: value } } 它是用来对Array (list)数据类型进行 增加 新元素的,相当于我们Python中 list.ap ...
- 【MongoDB】4.MongoDB 原子修改器的 极速修改
文档转自:http://blog.csdn.net/mcpang/article/details/7752736 对于文档的更新除替换外,针对某个或多个文档只需要部分更新可使用原子的更新修改器,能够高 ...
- mongodb修改器
mongodb修改器 转载自:http://blog.csdn.net/mcpang/article/details/7752736 mongodb修改器(\(inc/\)set/\(unset/\) ...
- [转载]MongoDB的$inc修改器
MongoDB的$inc修改器相当于编程语言中的 “+=”“$inc”只能用于操作数值类型的数据,包括整数.长整数和双精度浮点数,用于其他类型的数据会导致操作失败. >db.users.find ...
- python 全栈开发,Day124(MongoDB初识,增删改查操作,数据类型,$关键字以及$修改器,"$"的奇妙用法,Array Object 的特殊操作,选取跳过排序,客户端操作)
一.MongoDB初识 什么是MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介 ...
随机推荐
- 解决java.lang.NoClassDefFoundError: org/objectweb/asm/util/TraceClassVisitor
方案一: <dependency> <groupId>asm</groupId> <artifactId>asm-all</artifactId& ...
- CrashMonkey4IOS App测试
下载地址:https://github.com/vigossjjj/CrashMonkey4IOS 根据下载地址里面的说明安装一下,以下进行配置 1.进入CrashMonkey4IOS-master/ ...
- 网络请求 __ NSURLSession
首先配置into.plist文件 1. 添加 App Transport Security Settings , Type栏自动变为Dictionary 2. 点击左边箭头,使之向下,点击右边加号,添 ...
- Toad for Sqlserver
# 设置制表符 从sqlserver拷贝的存储过程粘贴到Toad,代码变得不整齐了,这就需要设置下制表符的大小.
- ElasticSearch性能优化官方建议
ES 手册 如何提高ES的性能 不要返回较大的结果集 ES是设计成一个搜索引擎的,只擅长返回匹配查询较少文档,如果需要返回非常多的文档需要使用Scroll. 避免稀疏 因为ES是基于Lucene来索引 ...
- ***PHP 数组排序 +php二维数组排序方法(PHP比较器)
PHP - 一维数组的排序函数 在本节中,我们将学习如下 PHP 数组排序函数: sort() - 以升序对数组排序 rsort() - 以降序对数组排序 asort() - 根据值,以升序对关联数组 ...
- android二维码生成
前生: 一维码:条形码 数字 缺点:不好看,占面积, 好了,请看效果图: 在准备之前我们要导一个包:core-3.2.1.jar 下载请访问: http://download.csdn.net/do ...
- 使用极光/友盟推送,APP进程杀死后为什么收不到推送(转)
为什么会存在这样的 问题,刚开始的时候我也搞不清楚,之前用极光的时候杀死程序后也会收到推送,但最近重新再去集成时就完全不好使了,这我就纳闷了,虽然Google在高版本上的android上面不建议线程守 ...
- JS代码判断IE6,IE7,IE8,IE9!
JS代码判断IE6,IE7,IE8,IE9!2011年12月15日 星期四 14:01做网页有时候会用到JS检测IE的版本,下面是检测Microsoft Internet Explorer版本的三种代 ...
- 普林斯顿算法课第五周作业_KdTree
作业地址:http://coursera.cs.princeton.edu/algs4/assignments/kdtree.html 作业难点: 1.如何构建KdTree,使用什么样的数据结构? 根 ...