MongoDB原生使用

创建数据库

1
use DATABASE_NAME

如果数据库不存在,则创建数据库,否则切换到指定数据库。

查看当前使用的数据库

1
db

查看所有数据库

1
show dbs

删除数据库

1
db.dropDatabase()

删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> db   # 查看当前数据库
test2
>
> db.dropDatabase() # 删除当前数据库
{ "ok" : 1 }
>
> show dbs;      # 查看剩余数据库,看看是否删除了
bi_online 0.000GB
cem_base 0.002GB
cem_base_MCD 0.003GB
cem_base_mcd_excel 0.792GB
cem_basic 0.002GB
cem_basic1 0.001GB
cem_demo 0.000GB
cem_dpca 0.000GB
cem_lppz 0.004GB
cem_lppz_3_8_test 0.000GB
cem_wrm 0.007GB
cem_wrm_180224 0.564GB
cem_wrm_180227 0.563GB
idybi 0.001GB
local 0.000GB
mobi 0.000GB
myblog 0.000GB

删除集合

1
2
3
4
5
6
7
> show collections;  # 查看当前有的集合
user
>
> db.user.drop() # 删除指定集合
true
> show collections; # 查看是否删除成功
>

创建集合

1
db.createCollection(name, options)

options 可以是如下参数:

  1. capped、布尔、(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
  2. autoIndexId、布尔、(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
  3. size、数值、(可选)为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。
  4. max、数值、(可选)指定固定集合中包含文档的最大数量。

在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。

例子1:

1
2
3
4
5
> db
test2
>
> db.createCollection("user")
{ "ok" : 1 }

例子2:

1
2
3
4
5
> db.createCollection("user1",{max:100,autoIndexId:true})
{
"note" : "the autoIndexId option is deprecated and will be removed in a future release",
"ok" : 1
}

例子3

1
2
> db.user2.insert({"name:":"user3"})
WriteResult({ "nInserted" : 1 })

查看

1
2
3
4
> show collections
user
user1
user2

在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。

插入文档

例1:

1
2
3
4
5
> db.user.insert({"name":"zhangsan","list":[1,2,3,4]})  # 插入
WriteResult({ "nInserted" : 1 })
> db.user.find() # 查看
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ] }
>

例2:

1
2
3
4
5
6
7
8
9
> doc = ({"name":"wang5",list:[6,7,8,9],"age":30})  # 创建好格式
{ "name" : "wang5", "list" : [ 6, 7, 8, 9 ], "age" : 30 }

> db.user.insert(doc) # 按照创建好的格式插入
WriteResult({ "nInserted" : 1 })

> db.user.find() # 查询插入的结果
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ] }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "wang5", "list" : [ 6, 7, 8, 9 ], "age" : 30 }

更新文档

1
2
3
4
5
6
7
8
9
10
> db.user.find()   #  查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ] }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "wang5", "list" : [ 6, 7, 8, 9 ], "age" : 30 }

> db.user.update({"name":"wang5"},{$set:{"name":"wangwu"}}) # 更新
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.user.find() # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ] }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "wangwu", "list" : [ 6, 7, 8, 9 ], "age" : 30 }

以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。

1
2
3
4
5
6
7
8
9
10
11
12
> db.user.find()   # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ] }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 30 }
>
>
> db.user.update({"name":"zhangsan"},{$set:{"age":70}},{multi:true}) # 修改符合name为zhangsan的所有数据
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
>
>
> db.user.find() # 查看结果
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 70 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 70 }

在3.2版本开始,MongoDB提供以下更新集合文档的方法:
db.collection.updateOne() 向指定集合更新单个文档

1
2
3
4
5
6
7
8
9
10
11
12
13
> db.user.find()  # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 70 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 70 }


> db.user.updateOne({"name":"zhangsan"},{$set:{"age":33}}) # 查询name等于zhangsan的第一条数据,并修改
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }


> db.user.find()
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 33 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 70 }
>

db.collection.updateMany() 向指定集合更新多个文档

1
2
3
4
5
6
7
8
9
10
11
> db.user.find()  # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 33 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 70 }

> db.user.updateMany({"name":"zhangsan"},{$set:{"age":100}}) # 查询所有name等于zhangsan的数据,并修改
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

> db.user.find() # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 100 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 100 }
>

删除文档

按条件删除

1
2
3
4
5
6
7
8
9
> db.user.find()  # 查询
{ "_id" : ObjectId("5aa25464480d660150d4287a"), "name" : "zhangsan", "list" : [ 1, 2, 3, 4 ], "age" : 100 }
{ "_id" : ObjectId("5aa254e8480d660150d4287b"), "name" : "zhangsan", "list" : [ 6, 7, 8, 9 ], "age" : 100 }

> db.user.remove({"name":"zhangsan"}) # 删除name等于zhangsan的数据
WriteResult({ "nRemoved" : 2 })

> db.user.find() # 查询
>

删除全部

1
>db.col.remove({})

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.user.find()  # 查询
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "zhang" }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "lisi" }
{ "_id" : ObjectId("5aa26468480d660150d4287e"), "name" : "wangwu", "age" : "30" }
{ "_id" : ObjectId("5aa26471480d660150d4287f"), "name" : "maliu", "age" : "30" }
{ "_id" : ObjectId("5aa26478480d660150d42880"), "name" : "tianqi", "age" : "30" }

> db.user.deleteOne({"age":"30"}) # 删除age等于30的第一条
{ "acknowledged" : true, "deletedCount" : 1 }

> db.user.find() # 查询
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "zhang" }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "lisi" }
{ "_id" : ObjectId("5aa26471480d660150d4287f"), "name" : "maliu", "age" : "30" }
{ "_id" : ObjectId("5aa26478480d660150d42880"), "name" : "tianqi", "age" : "30" }

1
2
3
4
5
6
7
8
9
10
11
12
> db.user.find()  # 查询
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "zhang" }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "lisi" }
{ "_id" : ObjectId("5aa26471480d660150d4287f"), "name" : "maliu", "age" : "30" }
{ "_id" : ObjectId("5aa26478480d660150d42880"), "name" : "tianqi", "age" : "30" }

> db.user.deleteMany({"age":"30"}) # 删除age等于30的所有数据
{ "acknowledged" : true, "deletedCount" : 2 }

> db.user.find() # 查询
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "zhang" }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "lisi" }

全部删除

1
db.user.deleteMany({})

查询文档

格式:db.collection.find(query, projection)

  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

以易读的方式来读取数据

1
2
3
4
5
db.user.find().pretty()

{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }

只需要查看一条数据,我们可以使用findOne

1
2
> db.user.findOne()
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu" }

条件查询:

  1. 等于

    1
    2
    > db.user.find({"age":40})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  2. 小于

    1
    2
    > db.user.find({"age":{$lt:41}})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  3. 小于等于

    1
    2
    > db.user.find({"age":{$lte:41}})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  4. 大于

    1
    2
    > db.user.find({"age":{$gt:39}})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  5. 大于等于

    1
    2
    > db.user.find({"age":{$gte:39}})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  6. 不等于

    1
    2
    3
    4
    > db.user.find({"age":{$ne:39}})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
    { "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
    { "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }
  7. and

    1
    2
    > db.user.find({"age":40,"name":"wangwu"})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
  8. or

    1
    2
    3
    4
    > db.user.find({$or:[{"name":"wangwu"},{"age":40}]})
    { "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
    { "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
    { "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }

一些简写的说明:

1
2
3
4
5
6
7
8
9
10
11
$gt -------- greater than  >

$gte --------- gt equal >=

$lt -------- less than <

$lte --------- lt equal <=

$ne ----------- not equal !=

$eq -------- equal =

查询某段时间内的数据:

1
2
db.CollectionAAA.find({ "CreateTime" : { "$gte" : ISODate("2017-04-20T00:00:00Z")  
, "$lt" : ISODate("2017-04-21T00:00:00Z") } }).count()

$type

1
2
3
4
> db.user.find({"name":{$type:2}})
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }

上面命令的含义是查询name字段,且值为String类型的

更多类型见下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Double						1	 
String 2
Object 3
Array 4
Binary data 5
Undefined 6
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255
Max key 127

limit

1
2
3
> db.user.find().limit(2)
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }

skip

skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。

1
2
3
> db.user.find().skip(1)
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }

查询结果只显示某些列

下面语句表示查询所有数据,且只显示name字段,且跳过第一条数据。当查询时同时使用sort,skip,limit,无论位置先后,最先执行顺序 sort再skip再limit。

1
2
3
> db.user.find({},{"name":1,"_id":0}).skip(1)
{ "name" : "wangwu" }
{ "name" : "wangwu" }

排序

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

1
2
3
4
5
6
7
8
9
> db.user.find().sort({"age":-1})
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }

> db.user.find().sort({"age":1})
{ "_id" : ObjectId("5aa26459480d660150d4287d"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa5fa76d3b0bc291895e59b"), "name" : "wangwu" }
{ "_id" : ObjectId("5aa2642f480d660150d4287c"), "name" : "wangwu", "age" : 40 }

索引

MongoDB使用 ensureIndex() 方法来创建索引,格式如下:

1
db.COLLECTION_NAME.ensureIndex({KEY:1})

语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可

1
2
3
4
5
6
7
> db.user.ensureIndex({"name":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}

ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)

1
2
3
4
5
6
7
> db.user.ensureIndex({"age":1,"name":-1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 4,
"numIndexesAfter" : 5,
"ok" : 1
}

建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。

1
2
3
4
5
6
7
> db.user.ensureIndex({"name":-1},{background:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 5,
"numIndexesAfter" : 6,
"ok" : 1
}

聚合

MongoDB中聚合的方法使用aggregate()

1
2
3
> db.user.aggregate([{$group:{_id:"$age",name:{$sum:1}}}])
{ "_id" : 40, "name" : 1 }
{ "_id" : null, "name" : 2 }

备份与恢复

备份

1
mongodump -h dbhost -d dbname -o dbdirectory

实例: 将test2备份到D盘

1
C:\Users\Rex>mongodump -h 127.0.0.1:27017 -d test2 -o d:

恢复

1
mongorestore -h <hostname><:port> -d dbname <path>

实例:将刚刚备份的test2的数据恢复到新的数据库test3中

1
C:\Users\Rex>mongorestore -h 127.0.0.1:27017 -d test3 d:/test2/

监控

  1. mongostat
    它会间隔固定时间获取mongodb的当前运行状态,并输出

  2. mongotop
    用来跟踪一个MongoDB的实例,查看哪些大量的时间花费在读取和写入数据。 mongotop提供每个集合的水平的统计数据

ObjectId

ObjectId 是一个12字节 BSON 类型数据,有以下格式:

  • 前4个字节表示时间戳
  • 接下来的3个字节是机器标识码
  • 紧接的两个字节由进程id组成(PID)
  • 最后三个字节是随机数
    1
    2
    3
    > var id = ObjectId()
    > id
    ObjectId("5aa630af9d56a7188e6bb65b")

ObjectId 中存储了 4 个字节的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过getTimestamp 函数来获取文档的创建时间:

1
2
> id.getTimestamp()
ISODate("2018-03-12T07:47:59Z")

ObjectId 转换为字符串

1
2
> id.str
5aa630af9d56a7188e6bb65b