mongodb使用教程

MongoDB入门总结

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组

1 安装

  • linux系统

    sudo apt-get install -y mongodb-org
    
  • windows系统

    下载MongoDB安装后进行安装

    启动mongodb C:\mongodb\bin\mongod --dbpath D:\software\MongoDB\Server\5.0\data\db

    添加安装bin目录路径至环境变量中: mongod --dbpath D:\software\MongoDB\Server\5.0\data\db

  • 使用docker安装

    # 搜索mongodb
    $ docker search mongodb
    
    # 拉取最新的mongo
    $ docker pull mongo
    
    # 查找mongo镜像
    $ docker images | findstr mongo
    mongo     latest    dfda7a2cf273    3 weeks ago    693MB
    
    # 创建容器
    $ docker create --name mongodb -p 27017:27017 -v /data/mongodb:/opt/mongodb/data mongo
    #启动容器
    $ docker start mongodb
    
    # 创建并启动容器
    $ docker run --name mongodb -p 27017:27017 -v /data/mongodb:/opt/mongodb/data mongo
    
    #进入容器
    $ docker exec -it mongodb /bin/bash
    
    #使用MongoDB客户端进行操作
    $ mongo
    >
    > # 查看所有数据库
    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    

2 mongodb的使用

2.1 数据库操作命令

  • show dbs
  • user test
  • show tables
  • db.dropDatabase()
# 进入mongo客户端
$ mongo
>
# 查看数据库
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

# 切换数据库(不存在的数据库, 当前已进入到test数据库)
> user test
>
> show dbs  # 并没有创建
admin   0.000GB
config  0.000GB
local   0.000GB

# 插入一条数据
> db.user.insert({id:1, name:"user"})
WriteResult({ "nInserted" : 1 })
> show dbs # 插入数据时会创建数据库
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

# 删除当前数据库
> db.dropDatabase()
{ "ok" : 1 }
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
>

2.2 集合命令

  • 直接创建结合:db.集合.insert({})
  • 手动创建集合:
    • db.createCollection(name, options)
    • db.createCollection(集合名)
    • db.createCollection(集合名, {capped: true, size: 10})
      • capped: 为true, 表示集合有上限
      • size: 表示字节数
  • 查看集合:show collections
  • 删除集合:db.集合名称.drop()
  • 检查集合是否设定上限:db.集合名称.isCapped()
  • 查看集合数据:db.集合名称.find()
# 集合user不存在时,则创建集合并插入数据
> db.user.insert({id:2, name: "user2"})
WriteResult({ "nInserted" : 1 })
>
# 创建集合
> db.createCollection('book')
{ "ok" : 1 }
>
# 检查集合是否设定上限
> db.user.isCapped()
false
>
# 查看集合数据
> db.user.find()
{ "_id" : ObjectId("61cbdcdf1adf966b6a398bb6"), "id" : 1, "name" : "user" }
{ "_id" : ObjectId("61cbf4db1adf966b6a398bb7"), "id" : 2, "name" : "user2" }
>

每一个文档都有一个_d唯一性值

  • objectID是一个12字节的十六进制数, 一共24位的字符串
    • 前4个字节为当前时间戳
    • 接下来的3个字节的机器id
    • 再接下来的2个字节是mongoDB服务进程id
    • 最后3个字节是简单的增量值

2.3 增删改查

2.3.1 插入数据(insert)

命令: db.collection.insert(document)

插入文档时, 如果 不指定_id, MongoDB会为文档自动分配唯一的objectid

# 插入单条数据
> db.stu.insert({name: 'lisi', age: 20})
WriteResult({ "nInserted" : 1 })

# 插入多条数据
> db.stu.insert([{name: 'liwu', age: 18}, {name: 'zhaoliu', age: 21}])
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})

# 查看集合数据
> db.stu.find()
{ "_id" : ObjectId("61cbfa9c1adf966b6a398bba"), "name" : "lisi", "age" : 20 }
{ "_id" : ObjectId("61cbfaca1adf966b6a398bbb"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbc"), "name" : "liwu", "age" : 18 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbd"), "name" : "zhaoliu", "age" : 21 }
>

2.3.2 保存(save)

命令:db.collection.insert(document)

可以新增一条或多条数据, 也可以修改一条或多条数据

传入_id时, 找到_id对应的文档会修改数据,找不到则新增数据

# 新增
> db.stu.save({name: 'zhangjie', age: 25})
WriteResult({ "nInserted" : 1 })
> db.stu.find()
{ "_id" : ObjectId("61cbfa9c1adf966b6a398bba"), "name" : "lisi", "age" : 20 }
{ "_id" : ObjectId("61cbfaca1adf966b6a398bbb"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbc"), "name" : "liwu", "age" : 18 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbd"), "name" : "zhaoliu", "age" : 21 }
{ "_id" : ObjectId("61cbfbce1adf966b6a398bbe"), "name" : "zhangjie", "age" : 25 }
>


# 修改, 传入_id时, 找到_id对应的文档会修改数据,找不到则新增数据
> db.stu.save({_id:ObjectId("61cbfa9c1adf966b6a398bba") , name: 'zhangjie', age: 26})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find()
{ "_id" : ObjectId("61cbfa9c1adf966b6a398bba"), "name" : "zhangjie", "age" : 26 }
{ "_id" : ObjectId("61cbfaca1adf966b6a398bbb"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbc"), "name" : "liwu", "age" : 18 }
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbd"), "name" : "zhaoliu", "age" : 21 }
{ "_id" : ObjectId("61cbfbce1adf966b6a398bbe"), "name" : "zhangjie", "age" : 25 }
>
db.stu.save([{"_id" : ObjectId("61cbfbce1adf966b6a398bbe"), name: 'zhangjie2', age: 25}, 
			 {"_id" : ObjectId("61cbfaf51adf966b6a398bbd"), name:'zhangjie3',age:28}])

2.3.3 查看数据(find)

2.3.3.1 方法

  • db.collection.findOne({条件})

    只返回第一个数据

  • db.collection.find({条件})

  • pretty(): 将结果格式化,不能和findOne一起使用

    db.collection.find({条件}).pretty()

2.3.3.2 比较预算符

  • 等于:没有判断符号
  • 小于:$lt
  • 小于等于:$lte
  • 大于:$gt
  • 大于等于:$gte
  • 不等于:$ne
# 查询年龄大于等于25的数据
> db.stu.find({age: {$gte: 25}})
{ "_id" : ObjectId("61cbfa9c1adf966b6a398bba"), "name" : "zhangjie", "age" : 26 }
{ "_id" : ObjectId("61cbfbce1adf966b6a398bbe"), "name" : "zhangjie", "age" : 25 }
{ "_id" : ObjectId("61cbfdcc1adf966b6a398bc0"), "name" : "zhangjie2", "age" : 25 }
{ "_id" : ObjectId("61cbfdcc1adf966b6a398bc1"), "name" : "zhangjie3", "age" : 28 }
>

2.3.3.3 逻辑运算符

  • and: 在json中直接写多条条件即可

    # 查询年龄大于等于25,并且性别为True的数据
    db.stu.find({age: {$gte:25}, gender: true})
    
  • or: 使用 $or, 值为列表, 列表中的条件为或的关系

    #查询年龄大于25,或者 性别为false的学生数据
    db.stu.find({$or: [{age: {$gt: 55}, gender: false}])
    

2.3.3.4 范围运算符

  • $in:在指定范围内的数据

  • $nin:不在指定范围的数据

    db.stu.find({age: {$in: [18, 25, 28]}})
    db.stu.find({age: {$nin: [18, 25, 28]}})
    

2.3.3.5 正则匹配

使用$regex,可以写正则表达式条件

db.stu.find({name: {$regex: '^zhan'}})

2.3.3.5 自定义条件

使用$where,值为js函数

db.stu.find({$where: function(){
	return this.age > 20;
}})

2.3.3.6 限制查询结果数据

  • skip(): 跳过指定数量的数据
  • limit(): 限制结果数量
db.stu.find().skip(2).limit(2)

2.3.3.7 投影

第一json参数是查询条件,第二个json参数是要查看的字段

想查看的字段设置为1, 不想查看的字段设置为0

> db.stu.find({}, {name: 1, _id:0})
{ "name" : "zhangjie" }
{ "name" : "zhangsan" }
{ "name" : "liwu" }
{ "name" : "zhaoliu" }
{ "name" : "zhangjie" }
{ "name" : "zhangjie2" }
{ "name" : "zhangjie3" }
>

2.3.3.8 排序(sort())

  • sort({})
    • 指定排序的字段, 升序设置1, 降序设置-1
# 按照 年龄升序,名字降序的规则进行排序
> db.stu.find({}, {_id:0}).sort({age:1, name:-1})
{ "name" : "liwu", "age" : 18 }
{ "name" : "zhangsan", "age" : 20 }
{ "name" : "zhaoliu", "age" : 21 }
{ "name" : "zhangjie2", "age" : 25 }
{ "name" : "zhangjie", "age" : 25 }
{ "name" : "zhangjie", "age" : 26 }
{ "name" : "zhangjie3", "age" : 28 }
>

2.3.3.9 统计个数(count)

  • count(): 可以传入json条件参数
> db.stu.count()
7
> db.stu.find().count()
7
> db.stu.find({age: {$gte: 25}}).count()
4
> db.stu.count({age: {$gte: 25}})
4

2.3.3.10 去重(distinct)

  • dinstinct(name, options): 可以传入json参数筛选条件
> db.stu.distinct('age')
[ 18, 20, 21, 25, 26, 28 ]
>
> db.stu.distinct('age', {age: {$gte: 25}})
[ 25, 26, 28 ]
>

2.3.4 更新(update)

  • 全文档覆盖更新
    • update({}, {})
  • 指定键更新
    • update({}, {$set: {}})
  • 没有匹配到数据就插入一条数据
    • update({}, {}, {upset: true})
> db.stu.update({name: 'lisi'}, {name: 'lisi2'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({name: 'lisi2'})
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbc"), "name" : "lisi2" }
>

> db.stu.update({name: 'lisi2'}, {$set: {age: 20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find({name: 'lisi2'})
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbc"), "name" : "lisi2", "age" : 20 }
>

2.3.5 删除(remove)

命令格式: remove({})

db.stu.remove({name: 'lisi2'})

2.4 聚合(aggregate)

聚合表达式:

db.集合名称.aggregate({管道: 表达式})

常用的管道

管道 说明
$match 过滤数据,只输出符合条件的文档
$group 将集合中的文档分组, 可用于统计结果
$project 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果, 相当于投影
$sort 将输入文档排序后输出
$limit 限制聚合管道返回的文档数
$skip 跳过指定数量的文档

常用的表达式

表达式 说明
\(sum | 求和, {\)sum:1}表示以1倍计数
$avg 计算平均值
$min 获取最小值
$max 获取最大值
$push 在结果文档中插入到一个数组中

2.4.1 $group

分组

  • _id 值为指定的字段进行分组
  • \(sum 按照指定的倍数计数, 例如: {\)sum: 1},{\(sum: "\)field"}
# 统计性别分组下组内条数
db.stu.aggregate({
	$group: {
		_id: "$gender",
		counter: {$sum: 1}
	}
})

# 统计性别分组下组内年龄之和, 组内人名使用列表存储
db.stu.aggregate({
	$group: {
		_id: "$gender",
		counter: {$sum: "$age"},
		name_list: {$push: "$name"}
	}
})

2.4.2 skip和limit

管道存在先后顺序, 管道前的结果会在管道后使用

  • $skip 跳过指定的文档数量
  • $limit限制返回的文档数据
> db.stu.aggregate({$limit: 2})
{ "_id" : ObjectId("61cbfa9c1adf966b6a398bba"), "name" : "zhangjie", "age" : 26 }
{ "_id" : ObjectId("61cbfaca1adf966b6a398bbb"), "name" : "zhangsan", "age" : 20 }

> db.stu.aggregate({$skip: 2})
{ "_id" : ObjectId("61cbfaf51adf966b6a398bbd"), "name" : "zhaoliu", "age" : 21 }
{ "_id" : ObjectId("61cbfbce1adf966b6a398bbe"), "name" : "zhangjie", "age" : 25 }
{ "_id" : ObjectId("61cbfdcc1adf966b6a398bc0"), "name" : "zhangjie2", "age" : 25 }
{ "_id" : ObjectId("61cbfdcc1adf966b6a398bc1"), "name" : "zhangjie3", "age" : 28 }
{ "_id" : ObjectId("61cc23e1342f4d9e69de0ba3"), "name" : "wangwu2", "age" : 20 }

2.5 索引

2.5.1 查看索引(getIndexes)

  • db.集合名称.getIndexes()
db.stu.getIndexes()

2.5.2 删除索引(dropIndex)

  • db.集合名称.dropIndex({"索引名称": 1})

2.5.3 创建索引(ensureIndex)

  • db.集合名称.ensureIndex()
    • unique: 为true时, 创建唯一索引
# 创建唯一索引
db.集合名.ensureIndex({'字段名': 1}, {'unique': ture})

# 创建符合索引
db.集合名.ensureIndex({'字段1': 1, '字段2': 2})

2.5.4 创建索引注意事项

  • 根据需要选择是否简历唯一索引。
  • 创建索引的升序和降序在单索引情况下不影响查询效率,但复合索引会有所影响。
  • 数据量巨大并且数据库的读取操作非常频繁时才需要创建索引;如果写入操作非常频繁,创建索引会影响写入速度。

2.6 权限

  • 使用admin数据库

    use admin
    
  • 创建超级用户

    db.createUser({'user': 'python', 'pwd': 'python', 'roles': ['root']})
    
  • 以权限认证方式启动mongodb数据库

    sudo mongod --auth
    
  • 登录验证

    use admin
    db.auth('python', 'python')
    
  • 删除用户

    db.dropUser(用户名)
    
posted @ 2019-07-13 11:34  三叶草body  阅读(256)  评论(0)    收藏  举报