博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mongodb修改器
阅读量:6802 次
发布时间:2019-06-26

本文共 8982 字,大约阅读时间需要 29 分钟。

增加、修改或删除键的时候,应该使用$修改器。要把"foo"的值设备"bar",常见的错误做法如下:
db.coll.update(criteria,{"foo":"bar"})
这种情况是不对的,实际上这种做法会把整个文档用{"foo":"bar"}替换掉,一定要使用以$开头的修改器来修改键/值对。
"$inc"与"$set"的用法类似,就是专门用来增加或减少数字的。"$inc"只能用于整数、长整数或双精度浮点数,要是在其他类型的数据上就会导致操作失败,其中包括很多语言会自动转换成数字的类型,例如null,布尔类型,或数字构成的字符串。"$inc"键的值必须为数字,不能使用字符串、数组和其他非数字的值,否则会报错,要修改其他类型,只能使用"$set"。
 
$set修改器
$set  修改器用来指定一个键值。如果这个键不存在,则创建他。
    
存在的情况:
    
> db.users.insert({"name":"liang","age":28})
> db.users.find().pretty();
{
    "_id" : ObjectId("59b0acb39176f02d0ab8adeb"),
    "name" : "liang",
    "age" : 28
}
> db.users.update({"name":"liang"},{$set:{"age":18}})
 
> db.users.find();
{ "_id" : ObjectId("59b0acb39176f02d0ab8adeb"), "name" : "liang", "age" : 18 }
不存在的情况:
> db.users2.insert({"name":"guo","age":38})
> db.users2.find();
{ "_id" : ObjectId("59b0dffa9176f02d0ab8aded"), "name" : "guo", "age" : 38 }
> db.users2.update({"name":"guo"},{$set:{"long":18}})
> db.users2.find();
{ "_id" : ObjectId("59b0dffa9176f02d0ab8aded"), "name" : "guo", "age" : 38, "long" : 18 }
如上所示,不存在 long字段,则创建了long字段。
 
$set用来修改内嵌文档
    
> db.users3.insert({"name":"liang","age":28,"city":{"sheng":"guangxi","shi":"liuzhou"}})
> db.users3.find().pretty();
{
    "_id" : ObjectId("59b0e1a1ac9cd6689ae73274"),
    "name" : "liang",
    "age" : 28,
    "city" : {
        "sheng" : "guangxi",
        "shi" : "liuzhou"
    }
}
> db.users3.update({"name":"liang"},{$set:{"city.sheng":"guangdong"}})
> db.users3.find().pretty();
{
    "_id" : ObjectId("59b0e1a1ac9cd6689ae73274"),
    "name" : "liang",
    "age" : 28,
    "city" : {
        "sheng" : "guangdong",
        "shi" : "liuzhou"
    }
}
 
$unset修改器
$unset修改用于将键删除
> db.users4.insert({"name":"guo","age":28})     
> db.users4.update({"name":"guo"},{$unset:{"age":1}})
> db.users4.find();
{ "_id" : ObjectId("59b0f70227ac1d037a75b622"), "name" : "guo" }
$inc修改器
$inc其用来增加或减少已有的键的键值,或者在键不存在的时候创建一个键。
    
> db.users5.insert({"name":"guo","age":28})     
增加10
> db.users5.update({"name":"guo"},{$inc:{"age":10}})
    
> db.users5.find();
{ "_id" : ObjectId("59b0f79027ac1d037a75b623"), "name" : "guo", "age" : 38 }
减少5
> db.users5.update({"name":"guo"},{$inc:{"age":-5}})
> db.users5.find();
{ "_id" : ObjectId("59b0f79027ac1d037a75b623"), "name" : "guo", "age" : 33 }
键不存在的时候创建一个键
> db.users5.update({"name":"guo"},{$inc:{"count":18}})
   
> db.users5.find();
{ "_id" : ObjectId("59b0f79027ac1d037a75b623"), "name" : "guo", "age" : 33, "count" : 18 }
 
下列age是字符类型,如果用 $inc,执行将会失败。如果用$set,语句为 {"$set":{"age":10}} 则会强制转换为 数字类型。
> db.users6.insert({"name":"guo","age":"28"})
WriteResult({ "nInserted" : 1 })
>
> db.users6.update({"name":"guo"},{$inc:{"age":10}})
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "Cannot apply $inc to a value of non-numeric type. {_id: ObjectId('59b0fa0027ac1d037a75b624')} has the field 'age' of non-numeric type String"
    }
})
> db.users6.find();
{ "_id" : ObjectId("59b0fa0027ac1d037a75b624"), "name" : "guo", "age" : "28" }
>
> db.users6.update({"name":"guo"},{$set:{"age":10}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users6.find();
{ "_id" : ObjectId("59b0fa0027ac1d037a75b624"), "name" : "guo", "age" : 10 }

 

数组修改器 $push
数组修改器,只能用在值为数组的键上。
    
不存在,就会创建一个数组
> db.blog.insert({"name":"liang"})   
> db.blog.update({"name":"liang"},{$push:{"messages":{"city":"shanghai","time":18}}})
>  db.blog.find().pretty();
{
    "_id" : ObjectId("59b1f96a63d4e58d60815f5e"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "shanghai",
            "time" : 18
        }
    ]
}
要增加的messages存在,就在末尾加入一个元素
> db.blog.update({"name":"liang"},{$push:{"messages":{"city":"liuzhou","time":20}}})
> db.blog.find().pretty();
{
    "_id" : ObjectId("59b1f96a63d4e58d60815f5e"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "shanghai",
            "time" : 18
        },
        {
            "city" : "liuzhou",
            "time" : 20
        }
    ]
}
如果要增加的messages数组中,"city" : "liuzhou"已经存在,或者 {"city":"liuzhou","time":20} 都存在,都会添加成功
> db.blog.update({"name":"liang"},{$push:{"messages":{"city":"liuzhou","time":22}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find().pretty();
{
    "_id" : ObjectId("59b1f96a63d4e58d60815f5e"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "shanghai",
            "time" : 18
        },
        {
            "city" : "liuzhou",
            "time" : 20
        },
        {
            "city" : "liuzhou",
            "time" : 22
        }
    ]
}
>  db.blog.update({"name":"liang"},{$push:{"messages":{"city":"liuzhou","time":20}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find().pretty();
{
    "_id" : ObjectId("59b1f96a63d4e58d60815f5e"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "shanghai",
            "time" : 18
        },
        {
            "city" : "liuzhou",
            "time" : 20
        },
        {
            "city" : "liuzhou",
            "time" : 22
        },
        {
            "city" : "liuzhou",
            "time" : 20
        }
    ]
}
 
数组修改器 $ne
$ne也是用来操作数组的修改器,在查询文档中,如果一个值不在数组里面就把他加进去,如果在不添加。
以上这种方式也可以使用$addToSet实现。
> db.blog2.insert({"name":"liang","messages":["shanghai","liuzhou"]})
下面nMatched为0表示没有修改
> db.blog2.update({"name":"liang","messages":{$ne:"shanghai"}},{$push:{"messages":"shanghai"}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
下面nMatched为1表示修改成功
> db.blog2.update({"name":"liang","messages":{$ne:"beijing"}},{$push:{"messages":"beijing"}})
> db.blog2.find().pretty();
{
    "_id" : ObjectId("59b206f163d4e58d60815f62"),
    "name" : "liang",
    "messages" : [
        "shanghai",
        "liuzhou",
        "beijing"
    ]
}
数组修改器 $addToSet
$addToSet也是用来操作数组的修改器,实现的功能与$ne修改器相同,且更为方便。使用$addToSet修改器可以避免重复。
> db.blog3.insert({"name":"liang","messages":["shanghai","liuzhou"]})
文档里已有{"messages":"shanghai"},修改完还是没有产生重复值
>  db.blog3.update({"name":"liang"},{$addToSet:{"messages":"shanghai"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.blog3.find();
{ "_id" : ObjectId("59b2365063d4e58d60815f67"), "name" : "liang", "messages" : [ "shanghai", "liuzhou" ] }
    
> db.blog3.update({"name":"liang"},{$addToSet:{"messages":"beijin"}})
> db.blog3.find();
{ "_id" : ObjectId("59b2365063d4e58d60815f67"), "name" : "liang", "messages" : [ "shanghai", "liuzhou", "beijin" ] }
数组修改器 $each
$each数组修改器要和$addToSet修改结合起来用,可以一次添加多个不同的值。例如上面的例子中,我们一次添加多个messages值, 如下:
> db.blog4.insert({"name":"liang","messages":["shanghai","liuzhou"]})
> db.blog4.update({"name":"liang"},{$addToSet:{"messages":{$each:["beijing","guangzhou","guilin"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog4.find();
{ "_id" : ObjectId("59b239fb63d4e58d60815f68"), "name" : "liang", "messages" : [ "shanghai", "liuzhou", "beijing", "guangzhou", "guilin" ] }
数组修改器 $pop
$pop修改器主要于从数组中删除元素,他可以从数组中的任何一端删除元素,
例如:
{$pop:{key:1}} 从数组末尾删除一个元素
{$pop:{key:-1}} 从数组头部删除一个元素
    
> db.blog5.insert({"name":"liang","messages":["shanghai","liuzhou","beijing","shenzhen"]})
> db.blog5.update({"name":"liang"},{$pop:{"messages":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog5.find();
{ "_id" : ObjectId("59b23f2263d4e58d60815f6b"), "name" : "liang", "messages" : [ "shanghai", "liuzhou", "beijing" ] }
>  db.blog5.update({"name":"liang"},{$pop:{"messages":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog5.find();
{ "_id" : ObjectId("59b23f2263d4e58d60815f6b"), "name" : "liang", "messages" : [ "liuzhou", "beijing" ] }
数组修改器 $pull
有时我们需要基于特定条件来删除元素,而不仅仅依据位置,就可以使用$pull修改器
$pull修改器和$pop修改类似,都是用来删除数组中的元素
$pull可以基于特定条件来删除元素
$pull会将所有匹配到的数据全部删掉,如对数组[1,2,1,1]执行pull 1,得到的结果就是只有一个元素的数组[2]
例如我们想删除messages数组中的"shanghai","liuzhou"元素:
    
> db.blog6.insert({"name":"liang","messages":["shanghai","liuzhou","beijing","shenzhen"]})
不能一次删除多个
> db.blog6.update({"name":"liang"},{$pull:{"messages":["shanghai","liuzhou"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.blog6.find();
{ "_id" : ObjectId("59b2422c63d4e58d60815f6e"), "name" : "liang", "messages" : [ "shanghai", "liuzhou", "beijing", "shenzhen" ] }
一次删除一个
> db.blog6.update({"name":"liang"},{$pull:{"messages":"shanghai"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog6.find();
{ "_id" : ObjectId("59b2422c63d4e58d60815f6e"), "name" : "liang", "messages" : [ "liuzhou", "beijing", "shenzhen" ] }
数组的定位修改器 $
若是数组有多个值,而我们只想对其中一部分进行操作,有两种方法可以实现这种操作。
两种方法操作数组中的值:通过位置或定位操作符("$")
数组都是以0开头的,可以将下标直接作为键来选择元素。
> db.blog7.insert({"name":"liang","messages":[{"city":"shanghai","time":"10"},{"city":"liuzhou","time":"20"}]})
    
> db.blog7.update({"name":"liang"},{$set:{"messages.1.city":"beijing"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog7.find().pretty();
{
    "_id" : ObjectId("59b2460363d4e58d60815f6f"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "shanghai",
            "time" : "10"
        },
        {
            "city" : "beijing",
            "time" : "20"
        }
    ]
}
在很多情况下,不预先查询文档就不能知道要修改数组的下标,为了克服这种困难,mongodb提供了定位操作符"$",用来定位查询文档已经匹配的元素,并进行更新,定位符只更新第一个匹配的元素。
> db.blog8.insert({"name":"liang","messages":[{"city":"shanghai","time":"10"},{"city":"liuzhou","time":"20"}]})
> db.blog8.update({"messages.city":"shanghai"},{$set:{"messages.$.city":"guangzhou"}})
    
> db.blog8.find().pretty();
{
    "_id" : ObjectId("59b24a3263d4e58d60815f70"),
    "name" : "liang",
    "messages" : [
        {
            "city" : "guangzhou",
            "time" : "10"
        },
        {
            "city" : "liuzhou",
            "time" : "20"
        }
    ]
}

转载于:https://www.cnblogs.com/liang545621/p/7491036.html

你可能感兴趣的文章
纯吐槽,关于现在的一些混乱情况.
查看>>
CentOS 7最小安装后,手动连接网络
查看>>
选择排序
查看>>
卷积神经网络(基础知识回顾)-第七讲
查看>>
inno setup中文支持
查看>>
js内存泄漏的问题?
查看>>
程序代码阅读与分析
查看>>
Linux 安装PHP PECL 百分百成功
查看>>
关于c++风格 code style
查看>>
svn 常用
查看>>
SVM支持向量机
查看>>
Asymptote 学习记录(2):例子阅读
查看>>
《常微分方程教程》习题2-2,4:一个跟踪问题
查看>>
陶哲轩实分析例17.2.3
查看>>
兩個集合之間的全體部分函數可以形成一個集合
查看>>
Elementary Methods in Number Theory Exercise 1.2.17
查看>>
认识拨号计划 - Dialplan
查看>>
DataTable 的数据导出到 Excel
查看>>
委托由浅入深学习
查看>>
BZOJ 1012 [JSOI2008]最大数maxnumber
查看>>