zoukankan      html  css  js  c++  java
  • mongodb修改器


    增加、修改或删除键的时候,应该使用$修改器。要把"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"
            }
        ]
    }





  • 相关阅读:
    设计模式系列
    Python3 系列之 可变参数和关键字参数
    设计模式系列
    【HANA系列】SAP HANA ODBC error due to mismatch of version
    【FICO系列】SAP FICO FS00修改科目为未清项目管理
    【FIORI系列】SAP OpenUI5 (SAPUI5) js框架简单介绍
    【HANA系列】SAP HANA SQL获取当前日期加若干天后的日期
    【HANA系列】SAP HANA SQL获取本周的周一
    【HANA系列】SAP HANA SQL获取当前日期
    【HANA系列】SAP HANA SQL获取当前日期最后一天
  • 原文地址:https://www.cnblogs.com/l10n/p/7491036.html
Copyright © 2011-2022 走看看