前言
本篇让小白快速入门MongoDB,会增删查改基本技能,并在Java中使用MongoDB。
MongoDB介绍
MongoDB是文档型数据库,属于NoSQL的数据库范畴,使用C++编写。它的数据结构非常的松散,类似于JSON格式,支持非常复杂的数据类型。它的查询类似于面向对象语言,而且还支持创建索引。不支持事务,所以性能高,适合存储低价值数据,比如日志。
怎么理解文档数据库?
MongoDB有库(MySQL也有库),有集合(类似于MySQL中的表),有文档(类似于MySQL中的行记录),一个文档的结构类似于JSON,不需要像MySQL那样需要定义表和字段,非常的灵活。你可以把MongoDB当做JSON一样使用。
MongoDB安装
Mac可以使用Homebrew来安装,参考该教程
我这里直接下载安装包,用的是4.2.0的版本,然后解压,然后创建数据目录:
# 创建默认数据目录
mkdir -p /data/db
进入bin文件夹,执行命令启动:
# 启动mongodb,默认端口是27017
sudo ./mongod
Mac没有启动成功,可以看下控制台输出的信息,一般都是没有权限或者没有某个文件夹,根据提示操作就可以。
启动成功后,进入交互终端:
# MongoShell 是一个交互式 JavaScript终端,它支持tab键补全功能
./mongo
# 退出交互终端
exit;
使用MongoDB
一个MongoDB实例可以创建多个数据库,默认保留了3个数据库,分别是admin、local、config,下面介绍一些常用的命令。
权限
# 切换到admin数据库
use admin
# 查看所有用户及权限
db.system.users.find().pretty();
# 在admin数据库创建用户并添加权限
db.createUser({
user:"admin", # 用户名
pwd:"123456", # 密码
roles:[{
role:"userAdminAnyDatabase",
db:"admin"
},
"readWriteAnyDatabase"
]
})
数据库操作
# 连接到远程MongoDB
mongo ip:port
# 可以帮助我们了解命令功能
help
# 查看所有数据库
show databases/dbs
# 查看当前所在库,默认test
db
# 切换到某个数据库,MongoDB有个特点是不存在就创建,如果use的这个数据库不存在就会创建
use 数据库名
# 删库,当一个库没有集合,默认会删除,也就是show databases是看不到的
db.dropDatabase();
集合操作
# 查看所有集合
show collections/tables;
# 创建集合
db.createCollection("集合名");
# 删除该集合
db.集合名称.drop()
# 修改集合名,这里的集合名称,一定是要完整的命名空间,格式为:数据库名.集合名称
db.adminCommand({renameCollection: "集合名称", to: "修改后的名称" })
文档操作
# 向某个集合插入数据,支持文档嵌套,如果没有这个集合默认就会创建
db.集合名.insert({name:"Alice",age:12,language:{first:"中文",second:"英文"}});
# 查询集合所有内容
db.集合名.find();
# 等值查找,查找name=张三 的文档
db.集合名.find({name:"张三"});
# 删除符合条件的文档,选项可以不填,默认删除所有,true,删除1条文档记录
db.集合名称.remove(删除条件,[选项]);
# 更新文档,加上{multi:true}表示更新多个文档
db.集合名称.update({key:"原来的值"},{$set:{key:"更新后的值"}},{multi:true});
# limit查询条数,不填查询所有
db.集合名.find().limit(查询数量);
# pretty 格式化结果
db.集合名.find().pretty();
# 只查某一个key的数据,表示只显示name这个key的数据,0表示禁止显示
db.集合名.find({},{"name":1});
# skip 跳过文档数量
db.集合名.find().limit(要跳过的数量);
# sort排序,1升序,-1降序
db.集合名.find().sort({key:-1});
索引操作
# 创建索引,可以创建多个称为复合索引,1表示索引升序,0表示降序
db.集合名.createIndex({key1:1,[key2:1]});
# 创建索引可能会阻塞数据库操作,添加参数background后台创建
db.集合名.createIndex({key1:1,[key2:1]},{background:true});
# 查看所有索引
db.集合名.getIndexes();
# 删除所有索引
db.集合.dropIndexes();
# 删除指定索引
db.集合.dropIndex("索引名称");
聚合操作
MongoDB也提供了跟MySQL一样的聚合操作,MongoDB利用aggregate聚合管道来完成的,管道是可以传递处理的。基本语法为:
db.集合名.aggregate(聚合操作);
操作名称 | 描述 |
---|---|
$group | 分组 |
$sum | 计算总和 |
$avg | 计算平均值 |
$min | 获取最小值 |
$max | 获取最大值 |
$match | 条件查询 |
$sort | 排序 |
$limit | 限制数量 |
$project | 获取 |
$lookup | 类似join连接 |
# 根据city分组,将age进行求和
# 等价SQL:select city as _id,sum(age) as sum from 集合名 group by city
db.集合名.aggregate([{$group: {_id:"$city",sum:{$sum:"$age"}}}]);
# 根据city分组,获取年龄大于3小于10,求出符合条件的总个数
# 等价于SQL:select city as _id,count(city) as count from 集合名
# where age > 3 and age < 10 group by city
db.集合名.aggregate([{$match: {age:{$gt:3,$lte:10}}},
{$group:{_id:"$city",count:{$sum:1}}}]);
# 根据age降序排序,1升序,-1降序
# 等价于SQL:select * from 集合名 order by age desc
db.集合名.aggregate([{$sort:{age:-1}}]);
# 其它的类似,实在不行,请网上搜索,熟能生巧的过程
数据类型
MongoDB中的数据类型:
数据类型 | 描述 | 举例 |
---|---|---|
Double | 浮点数 | {“money”:9.98} |
String | 字符串 | {“name”:”Alice”} |
Object | 对象 | {“name”:”Alice”,”language”:”{name:”Chinese”}”} |
Array | 数组 | {“movies”:[“T-1”,”T-2”]} |
ObjectId | 对象id | { “_id” : ObjectId(“5d77416a7c7acee07771ab85”)} |
Boolean | 布尔值 | {“isHandsome”:true} |
Date | 日期 | {“date”:new Date()} |
Null | 空值 | {“house”:null} |
Integer | 整型值 | 根据服务器来决定32还是64位 |
Timestamp | 时间戳 | 时间戳 |
Code | 可以包含JS代码 | {“method”:function(){}} |
Regular | 可以包含正则表达式 | {“v”:/learn/} |
ObjectId
ObjectId
具有生成快、占用小、可排序和值唯一等特点,它的值由 12 个字节组成,其中前 4 个 字节描述的是创建的时间戳。ObjectId
的组成如下:
[Unix 纪元以来的秒数 4字节][随机值 5字节][计数器 3字节]
在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id
作为主键。MongoDB 会为插入的文档生成 ObjectId
,如 5d14c2c54e5abe130c4a0660
,但开发者也可以在文档中定义该 _id
。因此,对默认生成的 _id
进行排序相当于按创建时间进行排序。
要注意的是,虽然默认生成的 ObecjtId
的值会随着时间的推移而变化,但它们不一定是按序的。这是因为 ObjectId
生成时用到的秒数以 秒
为单位,这就造成了同一秒内创建的 ObjectId
无法排序。还有,ObjectId
在客户端生成,所以它还会受到客户端系统时间的影响。
String
BSON 字符串的编码类型是 UTF-8,这使得可以轻松地将大多数国际字符存储在 BSON 字符串中。
typeof
可以通过typeof
来获取类型,例如:typeof "test"
,返回string
,typeof 2
,返回number
注意事项
- MongoDB中的JSON的key-value是有序的
- MongoDB区分类型和大小写
- 一个文档中key不能重复,否则后面的会覆盖前面的value值
- key的命名需要注意几点:
- 不能有空格
- 不建议使用”.”和”$”,它们有特殊意义
- 不建议用下划线”_”开头,它保留的
在Java中使用MongoDB
GitHub下载Demo
小结
本篇介绍了MongoDB的基本用法,会MySQL基本也就会了,而且它的操作类似于JSON,也很好理解。当然这只是个冰山一角,更多的用法可以参考官方文档。
参考资料
请你相信我所说的都是错的