mongodb的修改器

在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整、增加、或者删除键,还可以操作数组和内嵌文档。增加、修改或删除键的时候,应该使用$修改器。要把"foo"的值设备"bar",常见的错误做法如下:

db.coll.update(criteria,{"foo":"bar"})

这种情况是不对的,实际上这种做法会把整个文档用{"foo":"bar"}替换掉,一定要使用以$开头的修改器来修改键/值对。

1. $set修改器

$set  修改器用来指定一个键值。如果这个键不存在,则创建他,他对更新模式或者用户定义键来说非常方便。

> db.users.findOne()
{
        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
        "name" : "joe",
        "age" : 30,
        "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" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
        "name" : "joe",
        "age" : 30,
        "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":"[email protected]"}})
WriteResult({ "nInserted" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "author" : {
                "name" : "joe",
                "email" : "[email protected]"
        }
}
> db.blog.update({"author.name":"joe"},{"$set":{"author.name":"joe schmoe"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "author" : {
                "name" : "joe schmoe",
                "email" : "[email protected]"
        }
}
> db.blog.update({"title":"a blog post"},{"$set":{"author.name":"joe schmoe op"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "author" : {
                "name" : "joe schmoe op",
                "email" : "[email protected]"
        }
}
>

3. $unset修改器

$unset修改用于将键删除

> db.users.findOne()
{
        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
        "name" : "joe",
        "age" : 30,
        "sex" : "male",
        "location" : "Wisconsin",
        "favorite book" : [
                "cat‘s cardle",
                "foundation trilogy",
                "ender‘s game"
        ]
}
> db.users.update({"name":"joe"},{"$unset":{"favorite book":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("56fe7df8b322e3ff1dabf834"),
        "name" : "joe",
        "age" : 30,
        "sex" : "male",
        "location" : "Wisconsin"
}

4. $inc修改器

$inc其用来增加或减少已有的键的键值,或者在键不存在的时候创建一个键。

> db.games.insert({"game":"pinball","user":"joe"})
WriteResult({ "nInserted" : 1 })
> db.games.findOne()
{
        "_id" : ObjectId("5770a1394f533aa7535d46d4"),
        "game" : "pinball",
        "user" : "joe"
}
> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":50}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.games.findOne()
{
        "_id" : ObjectId("5770a1394f533aa7535d46d4"),
        "game" : "pinball",
        "user" : "joe",
        "score" : 50
}

为"score"键增加50再减少20

> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":50}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.games.findOne()
{
        "_id" : ObjectId("5770a1394f533aa7535d46d4"),
        "game" : "pinball",
        "user" : "joe",
        "score" : 100
}
> db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":-20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.games.findOne()
{
        "_id" : ObjectId("5770a1394f533aa7535d46d4"),
        "game" : "pinball",
        "user" : "joe",
        "score" : 80
}

以上"$inc"与"$set"的用法类似,就是专门用来增加或减少数字的。"$inc"只能用于整数、长整数或双精度浮点数,要是在其他类型的数据上就会导致操作失败,其中包括很多语言会自动转换成数字的类型,例如null,布尔类型,或数字构成的字符串。"$inc"键的值必须为数字,不能使用字符串、数组和其他非数字的值,否则会报错,要修改其他类型,只能使用"$set"。

如下:

> db.foo.insert({"count":"1"})
WriteResult({ "nInserted" : 1 })
> db.foo.find()
{ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : "1" }
> db.foo.update({},{"$inc":{"count":1}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "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:2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find()
{ "_id" : ObjectId("5770befc4f533aa7535d46d5"), "count" : 2 }
>

5. 数组修改器 $push

数组修改器,顾名思义它只可以用于操作数组,只能用在值为数组的键上。$push修改器如果指定的值已经存在,"$push"会想已有的数组末尾加入一个元素,要是没有就会创建一个新的数组。

> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "author" : {
                "name" : "joe schmoe op",
                "email" : "[email protected]"
        }
}
> db.blog.update({"title":"a blog post"},{"$unset":{"author":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{ "_id" : ObjectId("57709da84f533aa7535d46d3"), "title" : "a blog post" }
> db.blog.update({"title":"a blog post"},{"$push":{"comments":{"name":"joe","email":"[email protected]","content":"nice post"}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                }
        ]
}

为blog集合"a blog post"文档再增加一条评论:

> db.blog.update({"title":"a blog post"},{"$push":{"comments":{"name":"bob","email":"[email protected]","content":"good post"}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "bob",
                        "email" : "[email protected]",
                        "content" : "good post"
                }
        ]
}

6. 数组修改器 $ne

$ne也是用来操作数组的修改器,在查询文档中,如果一个值不在数组里面就把他加进去,如果在不添加。

> db.users.insert({"name":"joe","emails":["[email protected]","[email protected]","[email protected]"]})
WriteResult({ "nInserted" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"name":"joe","emails":{$ne:"[email protected]"}},{$push:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })                                    --nMatched为0表示没有修改
> db.users.update({"name":"joe","emails":{$ne:"[email protected]"}},{$push:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}

以上这种方式也可以使用$addToSet实现。

7. 数组修改器 $addToSet

$addToSet也是用来操作数组的修改器,实现的功能与$ne修改器相同,且更为方便。使用$addToSet修改器可以避免重复。

> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })     --原文档里已有"[email protected]",修改完也没有产生重复值
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}

8. 数组修改器 $each

$each数组修改器要和$addToSet修改结合起来用,可以一次添加多个不同的值。例如上面的例子中,我们一次添加多个email值, 如下:

> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{$each:["[email protected]","[email protected]","[email protected]"]}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 52,
                "errmsg" : "The dollar ($) prefixed field ‘$each‘ in ‘$each‘ is not valid for storage."
        }
})
> db.users.update({"_id":ObjectId("5770ca42e90c1adc80040a08")},{$addToSet:{"emails":{$each:["[email protected]","[email protected]","[email protected]"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
>

9. 数组修改器 $pop

$pop修改器主要于从数组中删除元素,他可以从数组中的任何一端删除元素,
例如:
{$pop:{key:1}} 从数组末尾删除一个元素
{$pop:{key:-1}} 从数组头部删除一个元素

> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"name":"joe"},{$pop:{"emails":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"name":"joe"},{$pop:{"emails":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}

有时我们需要基于特定条件来删除元素,而不仅仅依据位置,就可以使用$pull修改器

10. 数组修改器 $pull

$pull修改器和$pop修改类似,都是用来删除数组中的元素
$pull可以基于特定条件来删除元素
$pull会将所有匹配到的数据全部删掉,如对数组[1,2,1,1]执行pull 1,得到的结果就是只有一个元素的数组[2]

例如我们想删除emails数组中的"[email protected]"和"[email protected]"两个元素:

> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"name":"joe"},{$pull:{"emails":["[email protected]","[email protected]"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })  --好像不能一次删除多个,没有起作用
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> db.users.update({"name":"joe"},{$pull:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.update({"name":"joe"},{$pull:{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
        "_id" : ObjectId("5770ca42e90c1adc80040a08"),
        "name" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}

11. 数组的定位修改器 $

若是数组有多个值,而我们只想对其中一部分进行操作,有两种方法可以实现这种操作。
两种方法操作数组中的值:通过位置或定位操作符("$")

数组都是以0开头的,可以将下标直接作为键来选择元素。

> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "bob",
                        "email" : "[email protected]",
                        "content" : "good post"
                }
        ]
}
> db.blog.update({"title":"a blog post"},{$set:{"comments.1.name":"livan"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "livan",
                        "email" : "[email protected]",
                        "content" : "good post"
                }
        ]
}
> db.blog.update({"title":"a blog post"},{$set:{"comments.1.email":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "livan",
                        "email" : "[email protected]",
                        "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" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "livan",
                        "email" : "[email protected]",
                        "content" : "good post"
                }
        ]
}
> db.blog.update({"comments.name":"livan"},{$set:{"comments.$.email":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.update({"comments.name":"livan"},{$set:{"comments.$.name":"bob"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("57709da84f533aa7535d46d3"),
        "title" : "a blog post",
        "comments" : [
                {
                        "name" : "joe",
                        "email" : "[email protected]",
                        "content" : "nice post"
                },
                {
                        "name" : "bob",
                        "email" : "[email protected]",
                        "content" : "good post"
                }
        ]
}

《MongoDB权威指南中文版》

mongdb数组修改     http://blog.163.com/wm_at163/blog/static/1321734902012526111917601/

时间: 2024-10-19 14:22:06

mongodb的修改器的相关文章

MongoDB数组修改器更新数据

MongoDB数组修改器更新数据 2013-04-22 10:20:40      我来说两句    来源:姜志福 的BLOG    收藏  我要投稿 MongoDB数组修改器更新数据 这里,我们将了解一下数组修改器.数组,是我们经常看到和使用到的且非常有用的数据结构:它不仅可以通过索进行引用,还可以作为集合来使用.数组修改器,顾名思义,它是用来修改数组的,而不能用来修改整数或者字符串.数组修改器不多,就那么几个,但熟练掌握它后,将给我们带来非常方便的操作.下面,我们来了解一下: > db.us

MongoDB数组修改器更新数据(转)

MongoDB数组修改器更新数据 这里,我们将了解一下数组修改器.数组,是我们经常看到和使用到的且非常有用的数据结构:它不仅可以通过索进行引用,还可以作为集合来使用.数组修改器,顾名思义,它是用来修改数组的,而不能用来修改整数或者字符串.数组修改器不多,就那么几个,但熟练掌握它后,将给我们带来非常方便的操作.下面,我们来了解一下: > db.user.findOne() { "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"

MongoDB之修改器

MongoDB之修改器 $set  简单粗暴  {name: valuel} 直接将key对应的值赋值给value. db.xxoo.insert({}, {set: {key: value}}) # 相当于python中的dict['name'] = value $unset  简单粗暴的删除字段 {$unset: {name: 1}} # 相当于python中的del dict['name'] 0 原文地址:https://www.cnblogs.com/ZN-225/p/10174585.

Mongodb嵌套文档的修改-利用数组修改器更新数据

初学mongodb的可能和我一样有个疑问,mongodb是文档型的,那么如果一个文档嵌套另外一个文档,如果对这个嵌套文档进行增删改查呢. 就像如下这样:,如何对auther里面的name进行增删改查呢?这篇博客我们一起来看一下. 这里要用到几个修改器:$push,$pop,$pull 首先增加一个name: db.myFirstCollection.update({_id:1},{$push:{"auther":{"name":1}}}) 删除最后一个值,若要删除第

【MongoDB学习笔记8】深入MongoDB的更新(update)操作:修改器$set

MongoDB中文档存入数据库后用update方法更新文档,update方法有两个参数,例如 update(args1,args2) args1是指查询文档的条件: args2是指对查询到的文档进行什么样的修改: 一.文档替换 > joe1= db.post.findOne({"age":20}) {         "_id" :  ObjectId("54a530c3ff0df3732bac1680"),         "i

4,MongoDB 之 $关键字 及 $修改器 $set $inc $push $pull $pop MongoDB

我们在之前的 MongoDB 之 手把手教你增删改查 MongoDB - 2 中提到过 $set 这个系统关键字,用来修改值的对吧 但是MongoDB中类似这样的关键字有很多, $lt $gt $lte $gte 等等,这么多我们也不方便记,这里我们说说几个比较常见的 一.查询中常见的 等于 大于 小于 大于等于 小于等于 等于 : 在MongoDB中什么字段等于什么值其实就是 " : " 来搞定 比如 "name" : "路飞学城" 大于 :

MongoDB修改器的使用1

为什么要使用修改器?     通常我们只会修改文档的一部分,这时候更新整个文档就显得很麻烦,通常是通过原子性的更新修改器来完成. 1."$set"修改器    "$set"用来指定某个字段,如果不存在,则创建.这对部分更新或者添加来说就非常方便了. 如:  step1:往users数据库长如一条数据,通过JavaScript来完成:    var logs={name:"joe",age:30,sex:"female",loc

mongoDB-----针对某个或多个文档只需要部分更新可使用原子的更新修改器

update() db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } ) db.collection.update( criteria, objNew, upsert, multi )    四个参数的说明如下: criteria: update的查询条件,类似sql update查询内

MongoDB-比较符及修改器

数学比较符 $lt 小于 $lte 小于等于 $gt 大于 $gte 大于等于 $eq 等于 $ne 不等于 所有数据 > db.stutent.find() }) { "_id" : ObjectId("5d2ecd3d14ff51d814e40361"), "name" : "henry", "age" : 16, "sex" : "female", &qu