MongoDB文档操作:创建、更新、删除

 2015年07月06日    4790     声明


在MongoDB中文档是一个键值对的集合,文档是存储数据的基本单元。对文档的操作包括:向集合中添加新文档、向文档中插入数据、文档的更新和删除集中的文档等。


1. 文档的创建与数据插入

MongoDB中向集合添加新文档和插入数据,都是使用insert方法,当要插入的文档中没有"_id"键时,insert操作会自动增加一个,然后将其保存到MongoDB中。

db.tests.insert({"foo":"foo"})

向集合中批量插入多个文档时,可以使用批量插入方法batchInsert。一次插入较多的文档时,批量插入方法效率明显高单个插入。批量插入方法的使用与insert方法,但batchInsert方法插入的多个文档是做为数组参数传入的:

db.tests.insert({"_id":0}, {"_id":1}, {"_id":0})

当前版本的MongoDB能接受的最大消息长度是48M,所以无论是单个文档还是多个文档的插入,数据量不能超过48M。超过时就应该考虑对数据和请求进行拆分。当使用batchInsert进行批量插入时,插入过程中遇到错误(如:"_id"重复)会阻止后续文档的插入,如果需要忽略错误并继续插入后续文档,可以使用continueOnError选项。


2. 文档的更新

已存入数据库中的数据,可以使用update方法进行更新。update方法有两个参数: 一个是查询文档,用于过滤需要更新的目标文档;一个是修改器,即文档中要修改的内容

update(query, update)


2.1 文档替换

文档替换是指用一个新文档完全替匹配的文档。例如,对于如下一个文档:

{ "_id" : 1, "name" : "liuht", "blog" : "itbilu.com" }

可使用如下方式替换:

db.tests.update({'_id':1}, {name:'ht'})

使用替换更新时应当注意,如果查询条件匹配到多个文档,所有的文档都会被替换。


2.2 修改器的使用

2.2.1 $set修改器

$set修改器用于指定一个字段的值,字段不存在时,则会创建字段。例如,修改上面文档的"name"值,并增加一个"age"字段:

> db.tests.update({'_id':1}, { $set: { name:'liuht', age:30 }})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : "liuht", "age" : 30 }

修改错误或不在需要的字段,可以使用$unset方法将这个键删除。

> db.tests.update({'_id':1}, { $unset:{age:30}})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : "liuht" }

$set修改器,也可以用于修改内嵌文档。例如:

> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : { "firstName" : "liu", "lastName" : "ht" } }
> db.tests.update({'_id':1}, { $set:{ 'name.lastName':'tt' }})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : { "firstName" : "liu", "lastName" : "tt" } }


2.2.2 $inc修改器

$inc修改器用于字段值的增加和减少。$inc修改器与$set类似,不同的是$inc只能用于整型、长整型、浮点型等数字类型的值。例如,对上面文档的"age"字段+1:

{ "_id" : 1, "name" : "liuht", "age" : 30 }
> db.tests.update({'_id':1}, { $inc:{ age: 1 }})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : "liuht", "age" : 31 }


2.2.3 添加元素

对于已存在的数组元素,可以使用$push修改器向数组末尾添加一个元素,数组不存在则会创建数组。

> db.tests.update({'_id':1}, { $push:{ firends: 'sandy' }})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : "liuht", "age" : 31, "firends" : [ "sandy" ] }

如果需要向数据添加多个值,可以使用$each配合$push修改器添加。

> db.tests.update({'_id':1}, { $push: {firends: { $each: ['sandy', 'andy'] }}})
> db.tests.find({ _id: 1})
{ "_id" : 1, "name" : "liuht", "age" : 31, "firends" : [ "sandy", "sandy", "andy" ] }

如果希望数组元素是定长的,可以使用$slice配合$push修改器,这样就会保证数组不会超过最大长度。

> db.tests.update({'_id':1}, { $push: {firends: { 
                                          $each: ['sandy', 'andy'],
                                          $slice: -10 }}})

上例中,数组长度不会超过10,需要注意的是,$slice值必须是负数。限定长度的同时,可以使用$sort指定排序字段,以按一定规则对数据进行清理。


2.2.4 数组元素删除

数组元素的删除可以使用$pop从开头或末尾删除一个元素。

//从末尾删除
{ '$pop': { 'key': 1 } }
//从开头删除
{ '$pop': { 'key': -1 } }

如果需要删除数组中指定的值,可以使用$pull,例如:{ "$pull": {"tode": 1} }会将"tode"字段中所有值为1的元素删除。


2.2.5 数组元素修改

数组元素的修改,可以使用以"0"开始的下标定位修改,也可以使用定位操作符"$"进行修。对于如下一个文档:

> db.blog.posts.findOne()
{ "_id": 1, 
  "content": "……",
  "comments": [
    { "comment": "one",
      "author": "andy" },
    { "comment": "two",
      "author": "sandy" },
    { "comment": "three",
      "author": "cat" }
  ]}

对于以上文档,分别修改第一个位置和"author"为"sandy"的评论内容。

> db.blog.posts.update({ "_id": 1}, { "comments.0.comment": "hello"})
> db.blog.posts.update({ "commnets.author": "sandy"}, { "comments.$.comment": "hello"})


3. 文档的删除

集合中不在需要的数据可以使用remove方法删除数据,删除时可以接受一个查询文档做为可选参数,给定参数后,只有符合条件的数据才会被删除。

db.tests.remove()   //删除集中所有数据
db.tests.remove({"_id":{$gt:10}})  //只有_id大于10的文档才会删除

remove方法只要删除集合中的数据,集合本身及集合的无信息不会被删除。要将集合从数据库中删除可以使用drop方法,drop方法效率要高于remove