Mongodb权威指南笔笔记整理-文档操作
一、插入并保存文档
插入是想MongoDB中添加数据的基本方法,对目标集使用insert方法,插入一个文档:
> db.person.insert({name:"joe",age:24})
WriteResult({ "nInserted" : 1 })
这个操作会给文档增加一个"_id"建(要是原来没有的话),然后将其保存到MongoDB中。
二、删除文档
现在数据库有些数据,要删除它们:
> db.person.remove({})
WriteResult({ "nRemoved" : 4 })
上述命令会删除person集合中的所有文档、但不会删除集合本身,原有的索引也会保留、
remove函数也可以给定参数,删除符合条件的文档:
> db.person.remove({age:22})
WriteResult({ "nRemoved" : 1 })
删除数据是永久性的。不能撤销,也不能恢复、
三、更新文档
文档存入数据库以后,就可以使用update方法来修改它。update有两个参数,一个是查询文档,用来找出要更新的文档,另一个是修改器文档,描述对找到的文档要做哪些更改。更新操作是原子的:若是两个更新同时发生,先到达服务器的先执行,接着执行另一个,所以,互相有冲突的更新可以火速传递,并不会相互干扰:最后更新会取得胜利。
1.文档替换
更新最简单的情形就是完全用一个新的文档替代匹配的文档。这适用于模式结构发生了较大的编号的时候。例如,要对下面的用户文档做一个比较大的调整:
> db.person.findOne()
{
"_id" : ObjectId("534ca8cabda1672af56ee037"),
"name" : "joe",
"friends" : 32,
"enemies" : 2
}
想变成下面的样子
{
"_id" : ObjectId("534ca8cabda1672af56ee037"),
"relationships" : {
"friends" : 32,
"enemies" : 2
},
"username" : "joe"
}
可以用update来替换文档:
> var joe = db.person.findOne({name:"joe"})
> joe.relationships={"friends":joe.friends,"enemies":joe.enemies};
{ "friends" : 32, "enemies" : 2 }
> joe.username=joe.name;
joe
> delete joe.friends;
true
> delete joe.enemies;
true
> delete joe.name;
true
> db.person.update({name:"joe"},joe);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
常见错误及时查询条件匹配了多个文档,然后更新的时候由于第二个参数的存折就产生重复的"_id"值,数据库会报错,不做任何修改。
例如,有好几个文档都有相同的“name“,但是我们没有意识到:
> db.person.find()
{ "_id" : ObjectId("534cab49bda1672af56ee038"), "name" : "joe", "age" : 22 }
{ "_id" : ObjectId("534cab54bda1672af56ee039"), "name" : "joe", "age" : 25 }
{ "_id" : ObjectId("534cab5cbda1672af56ee03a"), "name" : "joe", "age" : 34 }
>
现在如果第二个joe过生日,要增加age的值,可能会这么做:
{ "_id" : ObjectId("534cab54bda1672af56ee039"), "name" : "joe", "age" : 25 }
> joe.age++;
25
> db.person.update({name:"joe"},joe);
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "The _id field cannot be changed from {_id: ObjectId(
'534cab49bda1672af56ee038')} to {_id: ObjectId('534cab54bda1672af56ee039')}."
}
})
>
为了避免这样的错误,最好确保更新总是指定唯一文档,例如通过像”_id“这样的键来匹配。
2.使用修改器
通常文档只会有一部分要更新。利用原子的更新修改器,可以使得这种部分更新极为高效。更新修改器是一种特殊的键,用来指定复杂的更新操作,比如调整、增加或者删除键,还可能是操作数组或者内嵌文档。
假设要在一个集合中放置网站的分析数据,每当有人访问页面的时候,就要增加pageviews的值。每个URL及对应的访问次数都已如下方式存储在文档中:
{ "_id" : ObjectId("5354712875267c51fec999fb"), "url" : "www.example.com", "page
views" : 52 }
每次有人访问页面,就通过url找到该页面,并用"$inc"修改器增加pageviews的值
> db.person.update({"url":"www.example.com"},{"$inc":{"pageviews":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
接着,执行一个find操作,会发现pageviews的值增加了1、
> db.person.find({url:"www.example.com"})
{ "_id" : ObjectId("5354712875267c51fec999fb"), "url" : "www.example.com", "page
views" : 53 }
>
1."$set"修改器入门
"$set"用来指定一个键的值、如果这个键不存在,则创建它、这对更新模式或者增加用户定义键来说非常方便。例如用户资料存储在下面这样的文档里:
> db.person.findOne()
{
"_id" : ObjectId("535474f175267c51fec999fc"),
"name" : "joe",
"age" : 30,
"sex" : "male",
"location" : "wisconsin"
}
非常简单的一段用户信息。要想添加喜欢的书籍进去,可以使用"$set“:
> db.person.update({"_id":ObjectId("535474f175267c51fec999fc")},
... {"$set":{"favorite_book":"war and peace"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
之后文档就有了”favorite_book“键。
> db.person.findOne()
{
"_id" : ObjectId("535474f175267c51fec999fc"),
"name" : "joe",
"age" : 30,
"sex" : "male",
"location" : "wisconsin",
"favorite_book" : "war and peace"
}
>
要是用户觉得喜欢的其实是另一本书,"$set"又能帮上忙:
> db.person.update({"name":"joe"},
... {"$set":{favorite_book:"green eggs and ham"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
用"$set"甚至可以修改键的数据类型。例如,如果用户又觉得喜欢的是一堆书,就可以将"favorite_book"键的值变成一个数组:
> db.person.update({name:"joe"},
... {"$set":{favorite_book:["cat's cradle","ender's game"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
如果用户突然发现自己不爱读书了,可以用"$unset"将键完全删除:
> db.person.update({name:"joe"},
... {"$unset":{favorite_book:1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
现在这个文档就和例子开始的时候是一样了。
也可以用"$set"修改内嵌文档:
> db.person.posts.findOne()
{
"_id" : ObjectId("53547c3a75267c51fec999fe"),
"title" : "A Blog Post",
"content" : "....",
"author" : {
"name" : "joe",
"email" : "<a href="mailto:joe@example.com" rel="nofollow" target="_blank">joe@example.com</a>"
}
}
> db.person.posts.update({"author.name":"joe"}, {"$set":{"author.name":"joe schm
oe"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
> db.person.posts.findOne()
{
"_id" : ObjectId("53547c3a75267c51fec999fe"),
"title" : "A Blog Post",
"content" : "....",
"author" : {
"name" : "joe schmoe",
"email" : "<a href="mailto:joe@example.com" rel="nofollow" target="_blank">joe@example.com</a>"
}
}
增加、修改或删除键的时候,应该使用$修改器。要把"foo"的值设置为"bar",常见的错误做法如下:
db.person.update({name:"joe"},{"foo":”bar"})
这会事与愿违。实际上这会将整个文档用{"foo":"bar"}替换掉。一定要使用$开头的修改器来修改键值对。
(责任编辑:IT) |