MongoDB CURD

1.shell基本操作

shell是一个功能完备的JavaScript解释器,可以运行任何JavaScript程序。

通过mongo.exe运行MongoDB shell后,shell会连到MongoDB服务器的test服务器,并将这个数据库连接赋值给全局变量db。

切换数据库

use DB_NAME

查看帮助文档

help

 2.数据库的创建和删除

通过切换数据库的命令来创建数据库,不过此时该数据库尚未真正创建起来,只有当数据库中创建了集合后,该数据才会真正建立起来。

use micromsg

 此时使用查看数据库的命令是看不到micromsg的

show dbs

 删除当前数据库

db.dropDatabase();

 3.集合的创建和删除

1)通过函数创建

db.createCollection(name, { size : ..., capped : ..., max : ... } );
e.g.
db.createCollection("user");

2)通过直接往不存在的集合里添加文档创建,此时MongoDB会自动创建该集合

var user = { "id": "100100100", "nickname": "路人甲" };
db.user.insert(user);

 3)删除集合

db.collections.drop();
e.g.
db.user.drop();

 4.文档的插入,读取,删除,更新

 1)插入,文档大小不能超过4MB

db.collectios.insert(obj);
e.g.
var user = { "id": "100100100", "nickname": "路人甲" };
db.user.insert(user);

 可以通过JS代码插入

for (var i = 0; i < 10; i++) {
	var user = { "id": 100100100 + i + "", "nickname": "路人甲" + i };
	db.user.insert(user);
}

批量插入:传递一个由文档构成的数组给数据库。

一次批量插入只是单个的TCP请求,避免了许多零碎请求所带来的开销;加上无需处理大量的消息头,批量插入会快一些。

注:批量插入的数量受限于Mongo消息的长度,目前为16MB。 

var users = [];
for (var i = 0; i < 10; i++) {
	var user = { "id": 100100100 + i + "", "nickname": "路人甲" + i };
	users[i] = user;
}
db.user.insert(users);

插入的原理

驱动程序将数据装换为BSON的形式,然后将其送入数据库。数据库解析BSON,检验是否包含"_id"键并且文档不能超过4MB,除此之外,不做别的数据验证,就只是简单地将文档原样存入数据库中。

可以使用--objcheck选项使服务器在插入之前检查文档结构的有效性。

 2)读取

这里进介绍简单的两个读取方式

--返回集合里面所有的文档

db.collectios.find();
e.g.
db.user.find();

 --返回集合里的第一个文档

db.collection.findOne();
e.g.
db.user.findOne();

3)删除

db.collectios.remove(query)

 query为查询文档,只有符合条件的文档才被删除

//删除"nickname"="路人甲0"的文档
db.user.remove({ "nickname": "路人甲0" });
//删除所有的文档
db.user.remove();

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

4)更新

更新操作是原子的:若两个更新同时发生,严格按照先后顺序执行。

db.collections.update(query, object[, upsert_bool, multi_bool])

query:查询文档,找出要更新的文档

object:修改器文档,描述对文档做哪些更改

(1)完全替换

db.user.update({"id": "100100100"}, { "id": "100100100", "nickname": "路人甲" });

 (2)$inc

累加修改器,对指定的键进行累加操作。

只能用于数字类型。

键不存在时创建一个键,并将其初始化为0 

//init + add
db.user.update({ "id": "100100110" }, {$inc: {"age": 1}});
//add
db.user.update({ "id": "100100110" }, {$inc: {"age": 1}});
          (3)$set 

用来指定一个键的值,如果这个键不存在,则创建它。 

//add
db.user.update({ "id": "100100109" }, {$set: {"age": 18}});
//update
db.user.update({ "id": "100100110" }, {$set: {"age": 17}});

 还可以用来操作内嵌文档的键 

db.user.update({ "id": "100100110" }, {$set: {"favorite_book": {"name": "三国"}}});
//add
db.user.update({ "id": "100100110" }, {$set: {"favorite_book.author": "罗"}});
//update
db.user.update({ "id": "100100110" }, {$set: {"favorite_book.author": "罗贯中"}});
//add nest doc + key 
db.user.update({ "id": "100100109" }, {$set: {"favorite_book.author": "罗"}});
          (4)$unset

 删除文档中的指定键 

db.user.update({ "id": "100100109" }, {$unset: {"age": 1}});
         同理,也可以用来操作内嵌文档的键
db.user.update({ "id": "100100110" }, {$unset: {"favorite_book.author": 1}});
          (5)$push 向已有的数组的末尾加入一个元素。要是没有就会创建一个数组。
//init + push
db.user.update({ "id": "100100101" }, {$push: {"favorite_books": "三国"}});
//push
db.user.update({ "id": "100100101" }, {$push: {"favorite_books": "三国"}});
//have added 2 elements
可以和$each组合,一次向数组添加多个元素
db.user.update({ "id": "100100101" }, {$push: {"favorite_books": {$each: ["三国", "水浒"]}}});
  (6)$addToSet  和$push功能一直,但是添加时可以避免重复。
//init + push
db.user.update({ "id": "100100102" }, {$addToSet: {"favorite_books": "三国"}});
//push
db.user.update({ "id": "100100102" }, {$addToSet: {"favorite_books": "三国"}});
//have added only 1 element
 和$each组合起来时,可以添加多个不同的值。
db.user.update({ "id": "100100102" }, {$addToSet: {"favorite_books": {$each: ["三国", "水浒", "西游"]}}});
 (7)$pop 移除数组index位置处的元素,index>0,从尾部开始,index<0从头部开始,index=0和index=1效果一样,值最后一个元素
db.user.update({ "id": "100100102" }, {$addToSet: {"favorite_books": {$each: ["三国", "水浒", "西游", "红楼", "聊斋"]}}});
db.user.update({ "id": "100100102" }, {$pop: {"favorite_books": 0}});
db.user.update({ "id": "100100102" }, {$pop: {"favorite_books": 1}});
db.user.update({ "id": "100100102" }, {$pop: {"favorite_books": -1}});
db.user.update({ "id": "100100102" }, {$pop: {"favorite_books": 6}});
 (8)$pull 基于特定条件来删除元素,而不是紧紧依靠位置
db.user.update({ "id": "100100102" }, {$push: {"favorite_books": {$each: ["三国", "水浒", "西游", "三国", "三国"]}}});
db.user.update({ "id": "100100102" }, {$pull: {"favorite_books": "三国"}});
 (9)数组的定位修改器 --通过数组下标(从0开始)定位元素
db.user.update({ "id": "100100104" }, {$addToSet: {"favorite_books": {$each: ["三国", "水浒", "西游", "红楼", "聊斋"]}}});
db.user.update({ "id": "100100104" }, {$set: {"favorite_books.0": "三国1"}});
 --通过$定位符来定位查询文档已经匹配的元素(只更新第一个匹配的元素)
db.user.update({ "id": "100100105" }, {$push: {"favorite_books": {"name": "三国", author: "罗"}}});
db.user.update({ "id": "100100105" }, {$push: {"favorite_books": {"name": "三国", author: "罗"}}});
//只修改了第一个元素对应的键值
db.user.update({ "favorite_books.author": "罗"}, {$set: {"favorite_books.$.author": "罗贯中"}});
 (10)upsert 一种特殊的更新。要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新文档。
db.user.update({ "id": "100100111" }, {$set: {"nickname" : "路人甲11", "age": 22}}, true);
 (11)save 在文档不存在时插入,存在时更新。
db.collections.save(obj)
 要是该文档有_id键,则调用upsert。否则,会调用插入
// upsert 
db.user.save({
  "_id" : ObjectId("53037ae4564524c4f605e0af"),
  "age" : 24,
  "id" : "100100112",
  "nickname" : "路人甲12"
});
// insert
db.user.save({
  "age" : 24,
  "id" : "100100112",
  "nickname" : "路人甲12"
});
 (12)更新多个文档 默认情况下,更新只能对符合匹配条件的第一个文档进行更改。要是多个文档符合条件,其余的文档就没有变化。当需要更新匹配的所有文档时,需要显式说明。
// update 1 doc
db.user.update({"id" : "100100112"}, {$set: {"age" : 26}});
// update 2 docs
db.user.update({"id" : "100100112"}, {$set: {"age" : 25}}, false, true);
 通过getLastError命令查看更新的文档数 
db.user.update({"id" : "100100112"}, {$set: {"age" : 25}}, false, true);
db.runCommand({getLastError: 1});
 (13)findAndModify命令

相当于 一次find + 一次update/remove + 一次getLastError命令 的原子操作 

db.runCommand({
	"findAndModify": "user",
	"query": {"id" : "100100112"},
	"sort": {"_id": 1},
	"update": {$set: {"nickname": "路人甲"}}
});

命令中每个键的对应值如下所示

findAndModify:集合名

query:查询文档

sort:排序结果的条件

update:修改器文档 / remove:boolean类型,表示是否删除文档 (update和remove必须有且仅有一个)

new:boolean类型,表示返回的是更新前的文档还是更新后的文档,默认为更新前的文档。

5.瞬间完成

对文档的插入,删除,更新都是瞬间完成的,它们都不等待数据库响应。

不等于异步操作,客户端将文档发送给服务器后就立刻干别的了。

有点:速度快,缺点:可能会丢失数据

6.安全操作

安全操作在执行了操作之后立即运行getLastError命令,来检查是否执行成功。 

驱动程序会等待数据库响应,然后适当地处理错误,一般会抛出一个可被捕获的异常。

7.请求和连接

MongoDB会为每一个数据库连接创建一个队列,存放这个连接的请求。

客户端发送的请求将会被放到队列的末尾,请求严格按照队列的顺序进行执行,因此单个连接总是能读到自己写得东西。

注:每个连接都有独立的队列,要是打开两个Shell,就有两个数据库连接。

在一个Shell中插入,之后在另一个Shell中查询不一定能得到插入的文档,可能会存在延时。

猜你喜欢

转载自siyuan-zhu.iteye.com/blog/2017725