千家信息网

03.Mongodb创建、更新和删除文档。

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,插入:>db.collectionName.insert({"bar":"baz")}批量插入:如果要向集合插入多个文档,使用批量插入会快一些。batchInsert函数实现批量插入,它接受一个文档数
千家信息网最后更新 2025年01月21日03.Mongodb创建、更新和删除文档。

插入:

>db.collectionName.insert({"bar":"baz")}

批量插入:
如果要向集合插入多个文档,使用批量插入会快一些。

batchInsert函数实现批量插入,它接受一个文档数组作为参数。

>db.collectionName.batchInsert([ {"_id:0}, {"_id":1}, {"_id":2} ])

>db.collectionName.find()

{"_id:0}

{"_id":1}

{"_id":2}

删除文档:

>db.collectionName.remove({})

上述命令只删除集合里面的文档,并不会删除集合本身,也不会删除集合的元信息。

remove函数可以接受一个查询文档作为限定条件作为可选参数。给定参数后,符合条件的文档才会被删除。

>db.collectionName.remove({"xxxx":true})

删除数据是永久性的,不能撤销,也不能恢复。

删除速度:

删除文档通常很快,但是如果要清空集合,使用drop直接删除集合会更快。

例如,插入测试数据:

>for (var i=0; i < 1000000; i++) {

... db.tmps.insert({"foo":i})

... }

使用remove删除,并记录花费时间:

var timeRemoves = function() {

var start = (new Date()).getTime();

db.tmps.remove({});

db.tmps.findOne();//Make sure the remove finishes before continuing

var timeDiff = (new Date()).getTime() - start;

print("Remove took:"+timeDiff+"ms");

}

更新文档:

db.collection.update(

,

,

{

upsert: ,

multi: ,

writeConcern:

}

)

update有两个参数,一个是查询文档,用于定位需要更新的文档,另一个是修改器(modifier)文档,用于说明要对找到的文档进行哪些修改。

更新操作是不可分割的:若是两个更新同时发生,先到达服务器的先执行,接着执行令一个。

·文档替换:

最简单的更新就是用一个新文档完全替换匹配的文档。这适用于进行大规模式迁移的情况。

例:

默认文档结构:

>db.tmps.findOne()

{

"_id" : ObjectId("54f125773d3fab4bb9d6dc63"),

"Name" : "joe",

"Friends" : 32,

"Enemies" : 2,

"Date" : ISODate("2015-02-28T02:18:21.858Z")

}

写一个definetmps.js文档,内容如下:

var replaceupdate = function(){

db.tmps.findOne();

var joe = db.tmps.findOne({"Name":"joe"});

joe.relationships = {"Friends":joe.Friends,"Enemies":joe.Enemies};

joe.Username = joe.Name;

delete joe.Friends;

delete joe.Enemies;

delete joe.Name;

db.tmps.update({"Name":"joe"},joe);

db.tmps.findOne();

}

然后再Shell中加载,并执行函数replaceupdate(),最后验证文档结构:

>load("definetmps.js")

true

>replaceupdate()

>db.tmps.findOne()

{

"_id" : ObjectId("54f125773d3fab4bb9d6dc63"),

"Date" : ISODate("2015-02-28T02:18:21.858Z"),

"relationships" : {

"Friends" : 32,

"Enemies" : 2

},

"Username" : "joe"

}

一个常见的错误是查询条件匹配到了多个文档,然后更新时由于第二个参数存在就产生重复的"_id"值。数据库就会抛出错误,任何文档都不会更新。

·使用修改器:

通常文档只会有一部分要更新。可以使用原子性的更新修改器,指定对文档中的某些字段进行更新。

1."$set"修改器入门:

"$set"用来指定一个字段的值。如果这个字段不存在,则创建它。这对更新模式或增加用户自定义键来说非常方便。

例:存储用户资料的文档,结构如下,

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 32,

"sex" : "male",

"location" : "Wisconsin"

}

我们要添加一个新键,用户喜欢的书籍进去,可以使用"$set"

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$set" : {"favorite book" : "war and peace"}})

然后我们文档就有了新键:

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 32,

"sex" : "male",

"location" : "Wisconsin",

"favorite book" : "war and peace"

}

这个时候喜欢书的键已经存在了,用户想换一本,可直接通过$set完成更新。

"$set"甚至可以修改键的类型。例如用户喜欢很多本书,就可以将"favorite book"键值变成一个数组:

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$set" : {"favorite book" : ["book1","book2","book3"]}})

如果用户不喜欢读书,可以用"$unset"将这个键值完全删除

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$unset" : {"favorite book" : 1}})

也可以用"$set"修改内嵌文档:

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 32,

"sex" : "male",

"location" : "Wisconsin",

"contact" : {

"email" : "123@qq.com",

"pnum" : "13212342112"

}

}

>db.tmps.update({"name":"joe"},

... {"$set":{"contact.email":"1450327195@qq.com"}})

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 32,

"sex" : "male",

"location" : "Wisconsin",

"contact" : {

"email" : "1450327195@qq.com",

"pnum" : "13212342112"

}

}

2.增加和减少"$inc"

"$inc"修改器用来增加已有键的值,改键不存在就会创建一个。

"$inc""$set"的用法类似,就是专门用来增加和减少数字的。"$inc"只能用于×××、长×××或双精度浮点型的值。

>db.tmps.update({"name":"joe"},

... {"$inc":{"age":1}})

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 33,

"sex" : "male",

"location" : "Wisconsin",

"contact" : {

"email" : "1450327195@qq.com",

"pnum" : "13212342112"

}

}

3.数组修改器

有一大类很重要的修改器可用于操作数组。数组是常用且非常有用的数据结构:它们不仅是可通过索引进行引用的列表,而且还可以作为数据集(set)来用。

4.添加元素"$push"

如果数组已经存在,"$push"会向已有数组末尾添加一个元素,没有则创建一个新数组。

如:

>db.tmps.update({"name":"joe"},

... {"$push":{"comments":{"name":"bob","email":"bob@qq.com"}}})

还添加继续使用"$push",这是一种比较简单的"$push"使用形式,也可以将它应用在一些比较复杂的数组操作中。

使用"$each"子操作符,可以通过一次"$push"操作添加多个值。

db.tmps.update({"name":"joe"},

... {"$push":{"comments":{"$each":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}}})

PS:通过"$set"的实现:

>db.tmps.update({"name":"joe"},

... {"$set":{"comments":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}})

如果希望数组的最大长度是固定的,那么可以将"$slice""$push"组合在一起使用,这样就可以保证数组不会超出设定好的最大长度,这实际上就得到了一个最多包含N个元素的数组。

>db.tmps.update({"name":"joe"},

... {"$push":{"favoritetop":{

... "$each":[{"name":"book","level":3},

... {"name":"music","level":1},

... {"name":"movie","level":4},

... {"name":"run","level":2}],

... "$slice":-3,

... "$sort":{"level":-1}}}})

注意:不能只将"slice"或者"$sort""$push"配合使用,且必须使用"$each"

5.将数组作为数据集使用

如果将数组作为数据集使用,保证数组元素不会重复。可以在查询文档中用"$ne"来实现。

(test)>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"aa@qq.com",

"bb@qq.com",

"cc@qq.com"

]

}

>db.tmps.update({"emails":{"$ne":"aa@qq.com"}}, {"$push":{"emails":"aa@qq.com"}})

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

>db.tmps.update({"emails":{"$ne":"dd@qq.com"}}, {"$push":{"emails":"a@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

由这里可以看出,$ne是在查询中做判断的,如果判断内容不存在则执行后面的$push操作。

也可以用"$addToSet"来实现:

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"aa@qq.com",

"bb@qq.com",

"cc@qq.com"

]

}

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":"aa@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":"dd@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

(test)>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"aa@qq.com",

"bb@qq.com",

"cc@qq.com",

"dd@qq.com"

]

}

"$addToSet""$each"组合起来,可以添加多个不同的值,而使用"$ne""$push"组合则不能实现。

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":{"$each":[

... "a@qq.com","b@qq.com","c@qq.com","d@qq.com"]}}})

6.删除元素

有几个从数组中删除元素的方法。若是把数组看成队列或者栈,可以用"$pop"这个修改器从数组任何一端删除元素。

>db.tmps.update({"name":"joe"},

... {"$pop":{"emails":1}}) //从数组末尾删除元素。

>db.tmps.update({"name":"joe"}, {"$pop":{"emails":-1}}) //从数组开头删除元素。

有时需要基于特定条件来删除元素,而不仅仅是依据元素位置,这时可以用"$pull"。它会将所有匹配文档全部删除,而不是只删除一个。对数组[1,1,2,1]执行pull 1,结果就只剩一个元素的数组[2]

7.基于位置的数组修改器

通过位置或者定位操作符("$")

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

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"bb@qq.com",

"cc@qq.com",

"dd@qq.com",

"a@qq.com",

"b@qq.com",

"c@qq.com"

]

}

>db.tmps.update({"name":"joe"},

... {"$set":{"emails.3":"aa@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"bb@qq.com",

"cc@qq.com",

"dd@qq.com",

"aa@qq.com",

"b@qq.com",

"c@qq.com"

]

}

很多情况下,不预先查询文档就不能知道要修改数组的下标,为了解决这个问题,Mongodb提供了定位操作符"$",用来定位查询已经匹配的数组元素,并进行更新。如下:

>db.blog.findOne()

{

"_id" : ObjectId("54f56483d9c146390ce21c58"),

"title" : "my frist blog.",

"content" : "a b c d e f g ....",

"comments" : [

{

"comment" : "good",

"author" : "joe",

"votes" : 0

},

{

"comment" : "it's ok",

"author" : "john",

"votes" : 2

}

]

}

>db.blog.update({"comments.author":"joe"},

... {"$set":{"comments.$.author":"jim"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.blog.findOne()

{

"_id" : ObjectId("54f56483d9c146390ce21c58"),

"title" : "my frist blog.",

"content" : "a b c d e f g ....",

"comments" : [

{

"comment" : "good",

"author" : "jim",

"votes" : 0

},

{

"comment" : "it's ok",

"author" : "john",

"votes" : 2

}

]

}

注意,定位符只更新第一个匹配元素。

特殊的更新:upsert

upsert更新,要是没有找到符合更新条件的文档,就会以这个条件和更新文档为基础创建一个新的文档。如果找到匹配文档,则正常更新。

update操作的第三个参数处为true,则是upsert更新!

db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},true) // 此为简写

db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},{upsert:true})

save函数:

使用save函数时,如果文档不存在,它会自动创建文档;如果文档存在,它就更新这个文档。它只有一个参数:文档。如果这个文档有"_id"键,save会调用upsert;否则调用insert

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 43,

"emails" : [

"bb@qq.com",

"cc@qq.com",

"dd@qq.com",

"aa@qq.com",

"b@qq.com",

"c@qq.com"

]

}

>var x = db.tmps.findOne()

(test)>x.age = 23

23

>db.tmps.save(x)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.tmps.findOne()

{

"_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

"name" : "joe",

"age" : 23,

"emails" : [

"bb@qq.com",

"cc@qq.com",

"dd@qq.com",

"aa@qq.com",

"b@qq.com",

"c@qq.com"

]

}

更新多个文档:

默认情况,更新只对匹配条件的第一个文档执行操作。要更新所有匹配,可以将update的第四个参数设置为true

>db.tmps.find()

{ "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 23 }

{ "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 23 }

{ "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 23 }

>db.tmps.update({"age":23}, {"$set":{"age":24}},false,true) //简写方式

>db.tmps.update({"age":23}, {"$set":{"age":24}},{upsert:false,multi:true})

>db.tmps.find()

{ "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 24 }

{ "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 24 }

{ "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 24 }

写入安全机制(write concern

是一种客户端设置,用于控制写入的安全级别。

PS:内容整理于《Mongodb权威指南》

文档 数组 更新 元素 修改器 参数 数据 条件 查询 用户 函数 多个 定位 结构 下标 位置 内容 字段 情况 操作符 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中稷济南互联网科技有限公司 弹琴软件开发 工作邮箱网络安全防范制度 游戏卡在服务器上自动连接 大数据和软件开发 高校网络安全人才培养创新 山西麻将软件开发诚信企业 将邮件发送到服务器是什么协议 网络安全保护制度怎么分级 stm服务器登录不上 国家网络安全日心得 sql数据库视频教程下载 湖南千度网络技术公司 计算机考试 数据库技术 金融业网络安全论坛 北京现代化软件开发产业 我的世界服务器哪个站桥最好玩 数据库审计本地操作 胡巧儿数据库应用设计在线看 服务器主板故障维修图解 做软件开发就是it吗 网络安全法主题班会总结 为什么网络安全就是国家安全 关系型数据库可以存储文档吗 智慧检务时代的网络安全 南漳电信网络安全活动 北京售货机软件开发 文化网络安全大赛是什么 二手服务器让进口吗 驻留在web服务器上的功能
0