MongoDB初使用
Contents
2020-06-18 更新: 增加数据库的迁移工作
MongoDB GUI
虽然我偏爱命令行, 但是数据库中, 使用GUI增删改查真的很方便, 可惜MongoDB没有 像phpMyAdmin这样的好工具, 我在试用了许多工具之后, 最后选择了Robo3t.
增删改查部分
最基础的增删改查一定是工作中用的最多的, 虽然工作中用的是PyMongo, 但是这里我只列出Mongo shell中的动作, 与PyMongo的动作基本是类似的.
1 | // 增 |
索引的建立
- 查看已经建立好的索引:
db.xxx.getIndexKeys()
或是db.xxx.getIndexes()
MongoDB也是使用B+树做为索引的, 所以加入索引后, 给定区间的查找 可以获得不错的效率, 多点随机查询会有一点慢.
详细官方文档可以查看这里: MonoDB Indexes.
我挑几个对我来说属于新知识的来讲, 但请大家一定以官方文档为准, 如果有任何错误, 请一定指出, 我会及时更新:
- MongoDB在建立表时, 会自动为
_id
字段增加索引. - 对于单个字段的索引, 如何排序并不重要, 无论正序还是逆序, MongoDB查询时都会使用; 对于多个字段的索引, 将会按照建立索引时字段的顺序 以及各个字段的指定顺序进行组织, 假如查询的顺序与索引的组织顺序不同, 索引 会失效.
- 分区索引(3.2版本以上), 符合某些条件的条目才会被索引记录.
- 稀疏索引: 存在某个字段的条目才会被索引记录, 官方推荐这个功能最好使用分区索引实现
- TTL索引, 索引字段只能是Date类型或是Date数据组成的数组, 只要有一个Date数据 达到了过期时间, 该条记录就会被删除.
Explain的使用
MySQL中, explain
绝对是优化查询的好帮手, 最主要的就是查看内层的搜索是否使
用了索引, 这是官方explain的使用,
比较详细的explain使用
目前来说, 我只看winningPlan
中的stage
, 为IXSCAN
的话基本就放心了,
并不代表其他字段不重要, 如果未来遇到, 会更新此博客.
Javascript与Mongo shell
在Mongo shell
中是可以使用Javascript
代码的, 但是Mongo shell
真的太难用了,
建议大家在Robo3t中加一个文件来运行. 下面是一套简单的代码, 使用Javascript
模拟了一次join
操作(跑跑看, 应该是容易理解的, 旨在说明Javascript代码可以使用):
1 | db.example.insert({'name': 'a', 'code': 1}) |
Aggregate的一些用法
MongoDB中许多操作单条语句是无法做到的,
aggregate
就适合处理简单的计算并返回结果.
仿Join($lookup)
$lookup
操作是MongoDB在3.2以后的版本中加入的Lookup官方文档,
类似于MySQL中的join
操作.
lookup
要与aggregate
语句配合使用Example
1 | // 与上面的js代码可以达到一致的效果 |
仿Group by
官方文档中作了详细的解释, groupby的也是Pipeline
的第一个例子.
我遇到的版本相关问题(不定期更新)
** 查看数据库版本: db.version();
**
aggregate与Mongo版本问题
不同版本的MongoDB shell
与MongoDB server
会提出warning, aggregate语句
也有可能会执行错误
1 | MongoDB shell version v4.0.2 |
我在执行中也遇到了下面的错误, 如果你也遇到了这样的TypeError. 你该考虑用服务器
上原始版本的MongoDB shell
了.
1 | > db.product.aggregate([{$group: {_id: "$p_id",count: { $sum: 1 }},},{$sort: {count: 1,},} ]) |
$ne, $eq 版本问题
$eq
在3.0之前的版本中是没有的, 想要实现{<field>: { $eq: <value> }}
这样的
效果, 就只能{"field": {'$not': {'$ne': <value>}}}
. 不过讲真, 这样用还是
有一点机械.
$lookup 版本问题
上面已经说过了, lookup是在3.2之后才支持, 处于3.2之前的版本, 只能自己手动的join!!!
explain 版本问题
3.0之后:
可以使用
db.comment.explain().aggregate([...])
可以使用db.comment.explain().find({...})
2.6 ~ 3.0:
db.comment.aggregate想要查看explain信息, 就要这样用了:
1 | db.comment.aggregate([ |
db.comment.find想要使用explain: 要这样:
db.admin.find({...}).explain()
2.6之前:
aggregate
不能explain. db.comment.find想要使用explain: 要这样:db.admin.find({...}).explain()
真的, 升级MongoDB是很有必要的, 也许许多人认为站着说话不腰疼. 但是, 尝试一下 平滑过渡数据库应该也算是工作的一部分, 重要的是将迁移流程以及主备做好, 能够即时的恢复.
数据的迁移工作
MongoDB的导入导出工作需要下载一些数据库工具, 选择对应的系统版本下载就可以了,
1 | # 导出数据至users.json |
MongoDB的事务
4.0之后才支持, 公司没有用这么新的版本, 也不用MongoDB的事务, 真的用到了再和大家分享吧.