MongoDB 命令行操作

MongoDB 是一种非关系型数据库。经典的关系型数据库有三层结构,database->table->record,
而 mongodb 与相对应的则是 datebase->collection->document,如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
+--------+ +----------+
|Database| | Database |
+--------+ +-----+----+
| |
| |
+----v---+ +-----v----+
| Table | |Collection|
+--------+ +----------+
| |
| |
+----v---+ +-----v----+
| Record | | Document |
+--------+ +----------+

1. 基本操作

本文使用的 MongoDB 版本是 3.2.3,操作系统是 MAC。

现在假设我们要创建一个 erp 数据库,然后在 erp 数据库中再创建一个叫 employee 的 collection,
employee 的文档结构示例如下:

1
2
3
4
{
"name": "Pol",
"gender": "male"
}

下面用 ‘>’ 表示 MongoDB shell 环境,用 ‘$’ 表示终端 shell 环境

  • 进入 MongoDB shell
1
2
3
4
# 本地链接,使用默认端口,即 mongo --host 127.0.0.1 --port 27017
$ mongo
# 连接远程数据库
$ mongo --host 100.100.220.75 --port 27017
  • 查看当前所有的数据库
1
2
3
> show dbs
shopping_test 0.002GB
test 0.000GB
  • 连接数据库
1
2
> use test
switched to db test
  • 查看当前连接的数据库
1
2
> db
test
  • 查看当前数据库中的所有集合
1
2
3
> show collections
user
user_test
  • 创建新的数据库

在 mongo 中,创建数据库的命令也是 use,比如创建数据库 erp,但是,当我们执行 use erp时,我们是看不到该数据库的,只有当往数据库插入数据时,它才会显示。执行下面的命令,往数据库中插入两条数据。

1
2
> db.employee.insert({"name": "Peter", "gender": "male"})
> db.employee.insert({"name": "Lucy", "gender": "female"})

2. 查找数据

通常情况下,find 方法的第 1 个参数指定查询条件,第 2 个参数指定要返回的字段。

  • 显示所有文档数据
1
2
3
> db.employee.find({})
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter", "gender" : "male" }
{ "_id" : ObjectId("56dfe2bd42ffea5f73a6af32"), "name" : "Lucy", "gender" : "female" }
  • 显示第 1 条文档
1
2
> db.employee.find({}).limit(1)
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter", "gender" : "male" }
  • 显示 name 为 Lucy 的文档
1
2
> db.employee.find({"name":"Lucy"})
{ "_id" : ObjectId("56dfe2bd42ffea5f73a6af32"), "name" : "Lucy", "gender" : "female" }
  • 显示 name 以 P 开头的文档,用到正则表达式,$options:$i 表示忽略大小写
1
2
> db.employee.find({'name':{'$regex':'^p', '$options':'$i'}})
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter", "gender" : "male" }
  • 只显示出 name 的文档,但没有 name 这个 key 的文档也会显示出来,用下面一条命令
1
2
3
4
5
> db.employee.insert({"gender": "male"})
> db.employee.find({},{"name":1})
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter" }
{ "_id" : ObjectId("56dfe2bd42ffea5f73a6af32"), "name" : "Lucy" }
{ "_id" : ObjectId("56dfe5df3c914ddb65f4f88f") }
  • 只显示出 name 的文档,且存在这个 name 这个 key
1
2
3
> db.employee.find({'name':{'$exists':true}},{"name":1})
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter" }
{ "_id" : ObjectId("56dfe2bd42ffea5f73a6af32"), "name" : "Lucy" }
  • 按 name 降序排序
1
2
3
4
> db.employee.find().sort({"name":-1})
{ "_id" : ObjectId("56dfe2b742ffea5f73a6af31"), "name" : "Peter", "gender" : "male" }
{ "_id" : ObjectId("56dfe2bd42ffea5f73a6af32"), "name" : "Lucy", "gender" : "female" }
{ "_id" : ObjectId("56dfe5df3c914ddb65f4f88f"), "gender" : "male" }

3. 导入与导出

3.1 导出

如果没有指定导出路径,则默认会在当前路径生成一个 dump 的文件夹。

1
2
3
4
5
6
7
8
9
10
11
$ mongodump -d erp -c employee
$ mongodump --host 100.103.224.75 --port 17017 -d erp -c items
$ mongodump --host 100.103.224.75 --port 17017 -d erp -c specs -q '{_id: {$gte: ObjectId("50ad7bce1a3e927d690385ec")}}'
dump
└── erp
├── employee.bson
└── employee.metadata.json
# 指定输出路径
$ mongodump -d erp -c employee -o ~/Documents

在某些情况下,我们可能需要导出最近 1000 条记录,可以这样做:

1.先用命令行排序,查出第 1001 条记录的 _id

1
> db.collection.find('', {'_id':1}).sort({_id:-1}).skip(1000).limit(1)

2.假设上面查出的记录的 _id 是 50ad7bce1a3e927d690385ec,然后利用 mongodump 的 -q 选项进行 dump 数据

1
$ mongodump -d 'your_database' -c 'your_collection' -q '{_id: {$gte: ObjectId ("50ad7bce1a3e927d690385ec")}}'

3.2 导入

  • 导入数据库 erp,其中含有一个叫 employee 的 collection
1
$ mongorestore ~/Downloads/dump
  • 将 employee 的 collection 导入数据库 test
1
$ mongorestore -d test ~/Downloads/dump/erp

4. 参考资料

  1. Getting Started with MongoDB (MongoDB Shell Edition)
  2. Is it possible to mongodump the last “x” records from a collection?
  3. MongoDB 正则表达式
  4. Performing regex Queries with pymongo