MongoDB文档更新操作

MongoDB文档更新

声明

​ 本文档在studio 3T中练习

文档替换

原来的josn串
{
    "_id" : ObjectId("59f005402844ff254a1b68f6"),
    "name" : "三国演义",
    "authorName" : "罗贯中",
    "authorGender" : "男",
    "authorAge" : 99.0
}
替换成
{
    "_id" : ObjectId("59f005402844ff254a1b68f6"),
    "name" : "三国演义",
    "author" : {
        "name" : "罗贯中",
        "gender" : "男",
        "age" : 99.0
    }
}

插入数据

db.yu_collect.insert({"_id" : ObjectId("59f005402844ff254a1b68f7"),"name" : "三国演义","authorName" : "罗贯中","authorGender" : "男","authorAge" : 99.0})

把该值赋给book

var book = db.yu_collect.findOne({name:"三国演义"})

首先添加字段author

book.author = {name:book.authorName,gender:book.authorGender,age:book.authorAge}

然后删除原来的字段:delete 字段名

delete book.authorAge
delete book.authorGender
delete book.authorName

重要的异步更新数据:update(query, update, options?)

db.yu_collect.update({name:"三国演义"},book)

结果显示

在这里插入图片描述

在这里插入图片描述

更新数据存在的问题

​ 问题:,MongoDB 只会匹配第一个更新的文档,假设我的 MongoDB 中有,如下多条数据

//多次执行
db.su_collect.insert({"name":"张三"}) 

然后有数据:

在这里插入图片描述

然后更新数据

db.su_collect.update({"name":"张三"},{"name":"李四"})
db.su_collect.find()

出现问题,没有全部更新,而是找到所有"name":"张三"的第一条进行了更新

在这里插入图片描述
MongoDB 的更新规则,即只更新第一条匹配结果。如果我们想将所有"name":“张三” 的更新为"name":“李四”,可以采用如:

db.su_collect.update({"name":"张三"},{$set:{"name":"李四"}},false,true)

首先我们将要修改的数据赋值给 set,set是一个修改器,我们将在下文详细讲解,然后后面多了两个参数,第一个 false 表示如果不存在 update 记录,是否将我们要更新的文档作为一个新文档插入,true 表示插入,false 表示不插入默认为 false第二个 true 表示是否更新全部查到的文档,false 表示只更新第一条记录,true 表示更新所有查到的文档

结果如下:

在这里插入图片描述

使用修改器

很多时候我们修改文档,只是要修改文章的某一部分,而不是全部,但是现在我面临这样一个问题,假设我有如下一个文档:

db.su_collect.insert({"name":"王八","age":18,"sex":"男"})

在这里插入图片描述

修改命令

db.su_collect.update({"name":"王八"},{"name":"六六"})

完了,整条数据没了

在这里插入图片描述

要解决这个问题,我们可以使用修改器

$set 修改器

正确的做法是这样的:

1.修改数据某个字段的值:update(query, update, options?)

//第一个false表示:如果没有匹配到,是否要插入一条新的,默认是false,第二个false表示:是否只更新第一条数据
db.su_collect.update({"name":"王八"},{$set:{"name":"六六"}},false,false)
db.su_collect.find()

结果是:

在这里插入图片描述

2.修改内部文档的某个值:update(query, update, options?)

db.su_collect.insert({
    "_id" : ObjectId("59f005402844ff254a1b68f6"),
    "name" : "三国演义",
    "author" : {
        "name" : "罗贯中",
        "gender" : "男",
        "age" : 99.0
    }
})

db.su_collect.update({"name":"三国演义"},{$set:{"author.name":"明代罗贯中"}})

结果如下

在这里插入图片描述

在这里插入图片描述

3.删除字段

db.su_collect.update({"name":"三国演义"},{$unset:{"author.name":"明代罗贯中"}})

结果
在这里插入图片描述

$inc 修改器

$inc 用来增加已有键的值,如果该键不存在就新创建一个,

db.su_collect.update({name:"三国演义"},{$inc:{"author.age":1}})

author字段的额age会加1,变成100.

注意 $inc 只能用来操作数字,不能用来操作 null、布尔等。

数组修改器

数组修改器有好几种,我们分别来看。
$push 可以向已有数组末尾追加元素,要是不存在就创建一个数组,还是以我们的上面的 book 为例,假设 book 有一个字段为 comments,是一个数组,表示对这个 book 的评论,我们可以使用如下命令添加一条评论:

db.su_collect.update({name:"三国演义"},{$push:{comments:"好书666"}})
db.su_collect.find()

在这里插入图片描述

{
    "_id" : ObjectId("59f042cfcafd355da9486008"),
    "name" : "三国演义",
    "author" : {
        "name" : "明代罗贯中",
        "gender" : "男",
        "age" : 100.0
    },
    "comments" : [ 
        "好书666"
    ]
}

如果想一次添加 3 条评论,可以结合 $each 一起来使用,如下:

db.su_collect.update({name:"三国演义"},{$push:{comments:{$each:["111","222","333"]}}})

我们可以使用 $slice 来固定数组的长度,假设我固定数组的长度为 5,如果数组中的元素不足 5 个,则全部保留,如果数组中的元素超过 5 个,则只会保留最新的 5 个,如下:

db.su_collect.update({name:"三国演义"},{$push:{comments:{$each:["444","555"],$slice:-5}}})

注意 $slice 的值为负数,运行结果如下:

{
    "_id" : ObjectId("59f042cfcafd355da9486008"),
    "name" : "三国演义",
    "author" : {
        "name" : "明代罗贯中",
        "gender" : "男",
        "age" : 100.0
    },
    "comments" : [ 
        "111", 
        "222", 
        "333", 
        "444", 
        "555"
    ]
}

我们还可以在清理之前使用 $sort 对数据先进行排序,然后再清理比如我有一个 class 文档,如下:

{
    "_id" : ObjectId("59f07f3649fc5c9c2412a662"),
    "class" : "三年级二班"
}

现在向这个文档中插入 student,每个 student 有姓名和成绩,然后按照成绩降序排列,只要前 5 条数据,如下:

db.su_collect.update({class:"三年级二班"},{$push:{students:{$each:[{name:"张一百",score:100},{name:"张九九",score:99},{name:"张九八",score:98}],$slice:5,$sort:{score:-1}}}})

$sort 的取值为 -1 和 1,-1 表示降序,1 表示升序。
上面的命令执行两次之后(即插入两次),结果如下:

{
    "_id" : ObjectId("59f07f3649fc5c9c2412a662"),
    "class" : "三年级二班",
    "students" : [ 
        {
            "name" : "张一百",
            "score" : 100.0
        }, 
        {
            "name" : "张一百",
            "score" : 100.0
        }, 
        {
            "name" : "张九九",
            "score" : 99.0
        }, 
        {
            "name" : "张九九",
            "score" : 99.0
        }, 
        {
            "name" : "张九八",
            "score" : 98.0
        }
    ]
}

slice和

sort不能只和push一起使用,还要加上each

$addToSet

我们可以在插入的时候使用 $addToSet,表示要插入的值如果存在则不插入,否则插入.

db.su_collect.update({name:"三国演义"},{$addToSet:{comments:"好书"}})

上面的命令执行多次之后,发现只成功插入了一条数据。也可以将 addToSet和

each 结合起来使用,如下:

db.su_collect.update({name:"三国演义"},{$addToSet:{comments:{$each:["111","222","333"]}}})

$pop

$pop 可以用来删除数组中的数据

如下:

db.su_collect.update({name:"三国演义"},{$pop:{comments:1}})

1 表示从 comments 数组的末尾删除一条数据,-1 表示从 comments 数组的开头删除一条数据。

$pull

使用 $pull 我们可以按条件删除数组中的某个元素

如下:

db.su_collect.update({name:"三国演义"},{$pull:{comments:"444"}})

表示删除数组中值为 444 的数据。

save

save 是 shell 中的一个函数,接收一个参数,这个参数就是文档,如果文档中有 _id 参数 save 会执行更新操作,否则执行插入操作,使用 save 操作我们可以方便的完成一些更新操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值