前言

本篇让小白快速入门MongoDB,会增删查改基本技能,并在Java中使用MongoDB。

MongoDB介绍

MongoDB是文档型数据库,属于NoSQL的数据库范畴,使用C++编写。它的数据结构非常的松散,类似于JSON格式,支持非常复杂的数据类型。它的查询类似于面向对象语言,而且还支持创建索引。不支持事务,所以性能高,适合存储低价值数据,比如日志。

怎么理解文档数据库?

MongoDB有库(MySQL也有库),有集合(类似于MySQL中的表),有文档(类似于MySQL中的行记录),一个文档的结构类似于JSON,不需要像MySQL那样需要定义表和字段,非常的灵活。你可以把MongoDB当做JSON一样使用。

MongoDB安装

Mac可以使用Homebrew来安装,参考该教程

我这里直接下载安装包,用的是4.2.0的版本,然后解压,然后创建数据目录:

  1. # 创建默认数据目录
  2. mkdir -p /data/db

进入bin文件夹,执行命令启动:

  1. # 启动mongodb,默认端口是27017
  2. sudo ./mongod

Mac没有启动成功,可以看下控制台输出的信息,一般都是没有权限或者没有某个文件夹,根据提示操作就可以。

启动成功后,进入交互终端:

  1. # MongoShell 是一个交互式 JavaScript终端,它支持tab键补全功能
  2. ./mongo
  3. # 退出交互终端
  4. exit;

使用MongoDB

一个MongoDB实例可以创建多个数据库,默认保留了3个数据库,分别是admin、local、config,下面介绍一些常用的命令。

权限

  1. # 切换到admin数据库
  2. use admin
  3. # 查看所有用户及权限
  4. db.system.users.find().pretty();
  5. # 在admin数据库创建用户并添加权限
  6. db.createUser({
  7. user:"admin", # 用户名
  8. pwd:"123456", # 密码
  9. roles:[{
  10. role:"userAdminAnyDatabase",
  11. db:"admin"
  12. },
  13. "readWriteAnyDatabase"
  14. ]
  15. })

数据库操作

  1. # 连接到远程MongoDB
  2. mongo ip:port
  3. # 可以帮助我们了解命令功能
  4. help
  5. # 查看所有数据库
  6. show databases/dbs
  7. # 查看当前所在库,默认test
  8. db
  9. # 切换到某个数据库,MongoDB有个特点是不存在就创建,如果use的这个数据库不存在就会创建
  10. use 数据库名
  11. # 删库,当一个库没有集合,默认会删除,也就是show databases是看不到的
  12. db.dropDatabase();

集合操作

  1. # 查看所有集合
  2. show collections/tables;
  3. # 创建集合
  4. db.createCollection("集合名");
  5. # 删除该集合
  6. db.集合名称.drop()
  7. # 修改集合名,这里的集合名称,一定是要完整的命名空间,格式为:数据库名.集合名称
  8. db.adminCommand({renameCollection: "集合名称", to: "修改后的名称" })

文档操作

  1. # 向某个集合插入数据,支持文档嵌套,如果没有这个集合默认就会创建
  2. db.集合名.insert({name:"Alice",age:12,language:{first:"中文",second:"英文"}});
  3. # 查询集合所有内容
  4. db.集合名.find();
  5. # 等值查找,查找name=张三 的文档
  6. db.集合名.find({name:"张三"});
  7. # 删除符合条件的文档,选项可以不填,默认删除所有,true,删除1条文档记录
  8. db.集合名称.remove(删除条件,[选项]);
  9. # 更新文档,加上{multi:true}表示更新多个文档
  10. db.集合名称.update({key:"原来的值"},{$set:{key:"更新后的值"}},{multi:true});
  11. # limit查询条数,不填查询所有
  12. db.集合名.find().limit(查询数量);
  13. # pretty 格式化结果
  14. db.集合名.find().pretty();
  15. # 只查某一个key的数据,表示只显示name这个key的数据,0表示禁止显示
  16. db.集合名.find({},{"name":1});
  17. # skip 跳过文档数量
  18. db.集合名.find().limit(要跳过的数量);
  19. # sort排序,1升序,-1降序
  20. db.集合名.find().sort({key:-1});

索引操作

  1. # 创建索引,可以创建多个称为复合索引,1表示索引升序,0表示降序
  2. db.集合名.createIndex({key1:1,[key2:1]});
  3. # 创建索引可能会阻塞数据库操作,添加参数background后台创建
  4. db.集合名.createIndex({key1:1,[key2:1]},{background:true});
  5. # 查看所有索引
  6. db.集合名.getIndexes();
  7. # 删除所有索引
  8. db.集合.dropIndexes();
  9. # 删除指定索引
  10. db.集合.dropIndex("索引名称");

聚合操作

MongoDB也提供了跟MySQL一样的聚合操作,MongoDB利用aggregate聚合管道来完成的,管道是可以传递处理的。基本语法为:

  1. db.集合名.aggregate(聚合操作);
操作名称 描述
$group 分组
$sum 计算总和
$avg 计算平均值
$min 获取最小值
$max 获取最大值
$match 条件查询
$sort 排序
$limit 限制数量
$project 获取
$lookup 类似join连接
  1. # 根据city分组,将age进行求和
  2. # 等价SQL:select city as _id,sum(age) as sum from 集合名 group by city
  3. db.集合名.aggregate([{$group: {_id:"$city",sum:{$sum:"$age"}}}]);
  4. # 根据city分组,获取年龄大于3小于10,求出符合条件的总个数
  5. # 等价于SQL:select city as _id,count(city) as count from 集合名
  6. # where age > 3 and age < 10 group by city
  7. db.集合名.aggregate([{$match: {age:{$gt:3,$lte:10}}},
  8. {$group:{_id:"$city",count:{$sum:1}}}]);
  9. # 根据age降序排序,1升序,-1降序
  10. # 等价于SQL:select * from 集合名 order by age desc
  11. db.集合名.aggregate([{$sort:{age:-1}}]);
  12. # 其它的类似,实在不行,请网上搜索,熟能生巧的过程

数据类型

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 的组成如下:

  1. [Unix 纪元以来的秒数 4字节][随机值 5字节][计数器 3字节]

在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id 作为主键。MongoDB 会为插入的文档生成 ObjectId,如 5d14c2c54e5abe130c4a0660,但开发者也可以在文档中定义该 _id。因此,对默认生成的 _id 进行排序相当于按创建时间进行排序。

要注意的是,虽然默认生成的 ObecjtId 的值会随着时间的推移而变化,但它们不一定是按序的。这是因为 ObjectId 生成时用到的秒数以 为单位,这就造成了同一秒内创建的 ObjectId 无法排序。还有,ObjectId 在客户端生成,所以它还会受到客户端系统时间的影响。

String

BSON 字符串的编码类型是 UTF-8,这使得可以轻松地将大多数国际字符存储在 BSON 字符串中。

typeof

可以通过typeof来获取类型,例如:typeof "test",返回stringtypeof 2,返回number

注意事项

  1. MongoDB中的JSON的key-value是有序的
  2. MongoDB区分类型和大小写
  3. 一个文档中key不能重复,否则后面的会覆盖前面的value值
  4. key的命名需要注意几点:
  • 不能有空格
  • 不建议使用”.”和”$”,它们有特殊意义
  • 不建议用下划线”_”开头,它保留的

在Java中使用MongoDB

GitHub下载Demo

小结

本篇介绍了MongoDB的基本用法,会MySQL基本也就会了,而且它的操作类似于JSON,也很好理解。当然这只是个冰山一角,更多的用法可以参考官方文档。

参考资料

请你相信我所说的都是错的