mongodb 增删改查

Catalogue
  1. 1. 创建/删除数据库
  2. 2. 插入文档
  3. 3. 修改
  4. 4. 删除文档
  5. 5. 条件操作符
  6. 6. limit 与 skip 操作符
  7. 7. 排序
  8. 8. 索引
  9. 9. 聚合
  10. 10. mongodb使用参考
  11. 11. 引用

创建/删除数据库

  • 创建
    use DATABASE_NAME
    如果数据库不存在,则创建数据库,否则切换到指定数据库。
    MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
eg:
> use runoob
switched to db runoob
> db
runoob
>

**你想查看所有数据库,可以使用 show dbs 命令:**

> show dbs
local 0.078GB
test 0.078GB
>

//可以看到,我们刚创建的数据库 runoob 并不在数据库的列表中,
//要显示它,我们需要向 runoob 数据库插入一些数据。
  • 删除数据库
    db.dropDatabase()
1
2
3
4
5
6
7
8
9
10
11
12
13
> show dbs
local 0.078GB
runoob 0.078GB
test 0.078GB
> use runoob
switched to db runoob
>
> db.dropDatabase()
{ "dropped" : "runoob", "ok" : 1 }
> show dbs
local 0.078GB
test 0.078GB
>
  • 删除集合
    mongo 里说的集合 = MySQL里的表
    db.collection.drop()
1
2
3
4
5
6
7
8
9
eg:
> use runoob
switched to db runoob
> show tables
user
> db.user.drop()
true
> show tables
>

插入文档

db.col.insert()
db.collection.insertOne():向指定集合中插入一条文档数据
db.collection.insertMany():向指定集合中插入多条文档数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// insert() 插入,find() 查询, pretty()格式化
> db.user.insert({'id':1,'age':12,'name':'maweizhuo'})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("5a58163b9a948caad01e31b4"), "id" : 1, "age" : 12, "name" : "maweizhuo" }
> db.user.find().pretty()
{
"_id" : ObjectId("5a58163b9a948caad01e31b4"),
"id" : 1,
"age" : 12,
"name" : "maweizhuo"
}
// insertOne
> db.user.insertOne({'id':2,'age':13,'name':'maweizhuo1'})
{
"acknowledged" : true,
"insertedId" : ObjectId("5a581a159a948caad01e31b5")
}
> db.user.find().pretty()
{
"_id" : ObjectId("5a58163b9a948caad01e31b4"),
"id" : 1,
"age" : 12,
"name" : "maweizhuo"
}
{
"_id" : ObjectId("5a581a159a948caad01e31b5"),
"id" : 2,
"age" : 13,
"name" : "maweizhuo1"
}

// 插入多条记录
> db.user.insertMany([{'id':4,'age':14,'name':'maweizhuo4'},{'id':5,'age':15,'name':'maweizhuo5'}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5a581aa39a948caad01e31b6"),
ObjectId("5a581aa39a948caad01e31b7")
]
}
> db.user.find().pretty()
{
"_id" : ObjectId("5a58163b9a948caad01e31b4"),
"id" : 1,
"age" : 12,
"name" : "maweizhuo"
}
{
"_id" : ObjectId("5a581a159a948caad01e31b5"),
"id" : 2,
"age" : 13,
"name" : "maweizhuo1"
}
{
"_id" : ObjectId("5a581aa39a948caad01e31b6"),
"id" : 4,
"age" : 14,
"name" : "maweizhuo4"
}
{
"_id" : ObjectId("5a581aa39a948caad01e31b7"),
"id" : 5,
"age" : 15,
"name" : "maweizhuo5"
}
>

修改

MongoDB 使用 update() 和 save() 方法来更新集合中的文档

  • update
    参数说明:
    query : update的查询条件,类似sql update查询内where后面的。
    update : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的
    upsert : (update+insert)可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
    multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
    writeConcern :可选,抛出异常的级别。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
> db.users.insert({'name':'maweihzuo','age':18,'tag':['mongo','nosql']})
WriteResult({ "nInserted" : 1 })
> show tables
users
> db.users.find().pretty()
{
"_id" : ObjectId("5a59ac4bc52de95ef9c85bfd"),
"name" : "maweihzuo",
"age" : 18,
"tag" : [
"mongo",
"nosql"
]
}
>

// update
----修改的数据没加$set标记,数据直接变为替换了,缺失name-----
> db.users.update({'age':18},{'age':19,"tag":['mongo','mysql','nosql']})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find().pretty()
{
"_id" : ObjectId("5a59ac4bc52de95ef9c85bfd"),
"age" : 19,
"tag" : [
"mongo",
"mysql",
"nosql"
]
}
// $set修改字段;$inc新增字段
// $set 如果新增字段不会报错
// $inc 后面如果修改原有的字段会报错
>db.users.update({'age':20},{$set:{'age':21,"tag":['mongo','mysql','nosql'],'name':'ma11'}},{multi:true})
>db.users.update({'age':21},{$inc:{'sex':1}},{multi:true})
>

// save() 经测试是存在则修改。不存在在添加
// 存在与否由是根据_id 来进行唯一区分的
> db.users.save({"age":1})

// 3.2 + 新特性
updateOne
updateMany
> db.test_collection.updateOne({"name":"abc"},{$set:{"age":"28"}})
> db.test_collection.updateMany({"age":{$gt:"10"}},{$set:{"status":"xyz"}})

– 更多示例update参数作用

1
2
3
4
5
6
7
8
9
10
11
12
只更新第一条记录:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
全部添加加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

删除文档

MongoDB remove() 函数是用来移除集合中的数据。

  • 参数说明:
    query :(可选)删除的文档的条件。
    justOne : (可选)如果设为 true 或 1,则只删除一个文档。
    writeConcern :(可选)抛出异常的级别。
1
2
// 好的习惯是先查询是否存在,在进行remove操作
db.user.remove({"name":3})

remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。

1
2
3
4
5
6
如删除集合下全部文档:
db.inventory.deleteMany({})
删除 status 等于 A 的全部文档:
db.inventory.deleteMany({ status : "A" })
删除 status 等于 D 的一个文档:
db.inventory.deleteOne( { status: "D" } )

条件操作符

(>) 大于 - $gt ----------greater than
(<) 小于 - $lt ----------less than
(>=) 大于等于 - $gte ----------greater than equal
(<= ) 小于等于 - $lte ----------less than equal
(!=) 不等于 $ne ----------- not equal
(=) 等于 $eq -------- equal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> db.user.find({},{_id:0}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>
> db.user.find({names:{$gte:5}},{_id:0}).pretty()
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>
// name 字段>1& <=5
> db.user.find({names:{$lte:5,$gt:1}},{_id:0}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
>
> db.user.find({names:{$lte:5,$gt:1},named:34},{_id:0}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
>

limit 与 skip 操作符

我们除了可以使用limit()方法来读取指定数量的数据外
还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
当查询时同时使用sort,skip,limit,无论位置先后,最先执行顺序 sort再skip再limit。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.user.find({},{_id:0}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>
> db.user.find({},{_id:0}).limit(2).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
>
> db.user.find({},{_id:0}).skip(1).limit(2).pretty()
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
> db.user.find({},{_id:0}).skip(2).limit(2).pretty()
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>

排序

sort()方法可以通过参数指定排序的字段,
并使用 1 和 -1 来指定排序的方式,其中1 为升序排列,而-1是用于降序排列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> db.user.find({},{_id:0}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>
> db.user.find({},{_id:0}).sort({name:-1}).pretty()
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
> db.user.find({},{_id:0}).sort({name:-1,name:1}).pretty()
{ "names" : 2, "name" : 34, "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : 40, "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : 45, "named" : 37, "namedd" : 38 }
>

索引

  • 背景
    索引通常能够极大的提高查询的效率,如果没有索引,
    MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
    这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,
    这对网站的性能是非常致命的。

    索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

  • 语法
    >db.COLLECTION_NAME.ensureIndex({KEY:1})
    语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
    有几个可选参数设置后台执行,唯一索引等。详情看教程

1
2
3
4
5
6
7
8
// 单个索引
>db.col.ensureIndex({"title":1})
>
// ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
>db.col.ensureIndex({"title":1,"description":-1})
>
// 在后台创建索引
db.values.ensureIndex({open: 1, close: 1}, {background: true})

聚合

  • 背景
    MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等)
    并返回计算后的数据结果。有点类似sql语句中的 count(*)。

  • 语法
    >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
    常用的聚合表达式
    $sum,$avg,$max,$min,$first,$last

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> db.user.find({},{_id:0}).pretty()
{ "names" : 2, "name" : "martin1", "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : "martin2", "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : "martin1", "named" : 37, "namedd" : 38 }
>
> db.user.aggregate([{$group:{_id:"$name", num_tutorial : {$sum:1}}}])
{ "_id" : "martin2", "num_tutorial" : 1 }
{ "_id" : "martin1", "num_tutorial" : 2 }
>
> db.user.aggregate([{$group:{_id:"$name", num_tutorial : {$sum:"$names"}}}])
{ "_id" : "martin2", "num_tutorial" : 5 }
{ "_id" : "martin1", "num_tutorial" : 9 }
> db.user.aggregate([{$group:{_id:"$name", num_tutorial : {$min:"$names"}}}])
{ "_id" : "martin2", "num_tutorial" : 5 }
{ "_id" : "martin1", "num_tutorial" : 2 }
> db.user.aggregate([{$group:{_id:"$name", num_tutorial : {$min:"$named"}}}])
{ "_id" : "martin2", "num_tutorial" : 35 }
{ "_id" : "martin1", "num_tutorial" : 34 }
  • 管道
    管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
    表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
    这里我们介绍一下聚合框架中常用的几个操作:
    $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
    $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
    $limit:用来限制MongoDB聚合管道返回的文档数。
    $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    $group:将集合中的文档分组,可用于统计结果。
    $sort:将输入文档排序后输出。
    $geoNear:输出接近某一地理位置的有序文档。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> db.user.aggregate([{$project:{name:1,named:1}}])
{ "_id" : ObjectId("5a59d48084421d11551bb6a0"), "name" : "martin1", "named" : 34 }
{ "_id" : ObjectId("5a5c0f172a78de2cabb5ad27"), "name" : "martin2", "named" : 35 }
{ "_id" : ObjectId("5a5c11e42a78de2cabb5ad28"), "name" : "martin1", "named" : 37 }
> db.user.aggregate([{$project:{_id:0}}])
{ "names" : 2, "name" : "martin1", "named" : 34, "namedd" : 34 }
{ "names" : 5, "name" : "martin2", "named" : 35, "namedd" : 36 }
{ "names" : 7, "name" : "martin1", "named" : 37, "namedd" : 38 }
> db.user.aggregate([{$match:{named:{$lte:37,$gte:34}}},{$group:{_id:"$name",num:{$sum:1}}}])
{ "_id" : "martin2", "num" : 1 }
{ "_id" : "martin1", "num" : 2 }
// $match用于获取named大于34小于或等于37记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
> db.user.aggregate([{$match:{named:{$lte:37,$gte:34}}},{$group:{_id:null,num:{$sum:1}}}])
{ "_id" : null, "num" : 3 }
// 跳过第一个,聚合操作
> db.user.aggregate([{$skip:1},{$group:{_id:"$name",num:{$sum:1}}}])
{ "_id" : "martin1", "num" : 1 }
{ "_id" : "martin2", "num" : 1 }

mongodb使用参考

可参考文章mongodb使用教程

引用

记录点滴,成为更好的自己。 — weizhuo.ma