算是学习下来精炼的笔记,但愿对你们有帮助。若是有问题欢迎你们指正。javascript
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。java
在高负载的状况下,添加更多的节点,能够保证服务器性能。mysql
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。sql
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档相似于 JSON 对象。字段值能够包含其余文档,数组及文档数组。mongodb
下面是与sql概念的对比。可以帮助咱们更好的理解mongodb。数据库
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表链接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
总结下来,传统的关系型数据库的内容结构是json
Mongodb与之对应的就是数组
不推荐用brew,由于如今mongodb闭源了,brew里已经搜索不到mongodb,不过仍是能够用brew安装的,这篇就不写了。服务器
直接去官网下载一个zip,解压完放到usr/local/里(control+shift+。能够显示隐藏文件夹),更名为mongodb。数据结构
而后添加一个环境变量就能够用了
$ export PATH=/usr/local/mongodb/bin:$PATH
这样就添加好了,反正就是如今能够用了。
能够用mongo来测试是否安装好了,若是都弄好了应该会弹出版本。
接下来就是新建data/db而后运行mongodb的步骤了。
不过mac os catalina如今有问题,跟目录不让写东西了,因此要曲线救国,根据mongodb给的最新的解决办法就是在/Users/(你的用户名)/data/db/
里当目录了
最后带上--dbpath= ,若是不添加会默认到/data/db里
sudo mongod --dbpath=/Users/Wangzirui/data/db
若是不是卡特琳娜那好说,
sudo mkdir -p /data/db
而后 sudo mongod
就完事了。
更改catelina限制以后(关闭sip)。能够直接用 sudo mount -uw / 更改跟目录权限,就能够直接sudo mongod就完事了。
而后另外一个终端进入/usr/loacl/mongodb/bin/
而后./mongo就启动了mongo的客户端
或者直接mongo也能够。
启动服务:
sudo mount -uw /
sudo mongod
启动客户端:
mongo
collectionname代指相对应的collcetion名字(mysql里叫表,Mongodb里叫collection,都是一个数据库里的一种结构) 如今操做的不是表也不是集合,而是集合里的一个数据结构叫作document,文档,文档至关于mysql里的一个记录行。
通过上面的讲述,能了解到一点,基于database来查询collections里的数据都是经过db.collcetion_name.方法 来进行操做的,同理。对document的查询,咱们以前也在查看collection时用过,他就是find()方法。
find里面能够加参数,不加的话就是现实collection里全部的document。
投影
经过Js函数来筛选数据
$where:
db.collection_name.find({$where:function(){
Return age>10}})
根据某个字段排序
计数
count()
直接在查询出来的后面加上就能够显示了
db.collection_name.find({$where:function(){
Return age>10}}).count()
去重
直接在终端输入,不要在mongodb的客户端输入
mongodump -h hostname -d dbname -o dbdirectory
-h 服务器地址,能够指定端口号。本机能够不填
-d 具体Mongodb下哪一个数据库
-o 你想保存到本地的什么地方
例如本机 下在termainal直接输入 mongodump -d laotie -o wenjianjia
而后就把 laotie这个数据库保存到Users/wangzirui/wenjianjia这个文件夹里了
一样直接在终端输入
Mongorestore -h hostname -d dbname --dir
-h 服务器地址,能够指定端口号。本机能够不填
-d 你想让这个数据库叫什么,不必定是原名
-Dir 这个备份文件在哪里
aggregate,就是一个管道,相似中间件或者是函数的链式调用。最终导出想要的数据。
首先放一个student集合的数据,聚合全部的操做都是按照这些数据来的。
> db.student.find() { "_id" : ObjectId("5e003b92f197cb08dc74a311"), "name" : "duanyuxin", "age" : 21, "sex" : "male" } { "_id" : ObjectId("5e003b92f197cb08dc74a312"), "name" : "baiyu", "age" : 20, "sex" : "male" } { "_id" : ObjectId("5e003f66f197cb08dc74a313"), "name" : "wangzirui", "age" : 22, "sex" : "male" } { "_id" : ObjectId("5e003f8ff197cb08dc74a314"), "name" : "zhuhuan", "age" : 22, "sex" : "female" } { "_id" : ObjectId("5e003f8ff197cb08dc74a315"), "name" : "caoyajing", "age" : 12, "sex" : "female" }
先放例子:
> db.student.aggregate({ $group:{_id:"$sex",avg_age:{$avg:"$age"}} }) { "_id" : "male", "avg_age" : 21 } { "_id" : "female", "avg_age" : 17 }
在$group
的对象里,前面开头的域(字段)表明下面将要输出的域的值。 后面的$sex
表示的是我拿什么东西当作group分组的键值。若是我针对不一样的age分组,那么我将会获得
> db.student.aggregate({ $group:{_id:"$age"} }) { "_id" : "12"} { "_id" : "20"} { "_id" : "21"} { "_id" : "22"}
的结果。
接着说avg_age,这个域是咱们本身定义的。(多是先入为主,我总以为说字段更为适应,你们也更容易理解),叫什么都行,可是后面$avg:"$age"
的意思就是,首先前面$avg
就是取平均值,取得就是你后面$age
的平均值。而后输出的时候就打印"avg_age:前面符合id分类的文档的age平均值"
若是想计算整个文档的某些值,仅须要把_id:null
然就能够不分组,直接用整个文档来算。
> db.student.aggregate({ $group:{_id:null,avg_age:{$avg:"$age"}} }) { "_id" : null, "avg_age" : 19.4 }
另外讲一个$sum的用法,先看怎么用。
> db.student.aggregate({ $group:{_id:null,count:{$sum:1},avg_age:{$avg:"$age"}} }) { "_id" : null, "count" : 5, "avg_age" : 19.4 }
在刚才的基础上加了一个$sum:1
里 $sum
顾名思义是求和用的,后面是求和的倍数,若是你设成2的话结果就乘2变成10.通常用来计数的话广泛仍是设置成1的。
$group
不止能够添加一个分组条件,也能够添加多个分组条件,若是把每一个条件都对应文档的域,那么就至关于去重操做。
> db.student.aggregate({ $group:{_id:{name:"$name",sex:"$sex",age:"$age"}} })
而后接下来用别的通道来进行下一步的操做就能够了。可是接下来的操做要用到的属性就是$_id.name
相似的。由于咱们去重时把属性都给了叫_id的域。
重构输出结构,也就是在aggregete的通道特性,然在最后调整你想要的输出结构。大致上和投影相似。
放栗子:
> db.student.aggregate( { $group:{_id:null,count:{$sum:1},avg_age:{$avg:"$age"}} }, { $project:{sex:"$_id",count:"$count",avg_age:"$avg_age"} } ) { "_id" : null, "sex" : null, "count" : 5, "avg_age" : 19.4 }
同理,能够用1 或者0代替。具体不举例子了,没什么大用。
听名字就知道是过滤用的,虽然find一样能够过滤,可是不能将find出来的结果传给下一个管道。
好比说你想呀知道年龄大于20的男生和女生分别有几我的
能够按照下面的方式操做
db.student.aggregate( {$match:{age:{$gt:19}}}, {$group:{_id:"$sex",count:{$sum:1}}}, {$project:{_id:0,sex:"$_id",count:1}} ) { "count" : 3, "sex" : "male" } { "count" : 1, "sex" : "female" }
大致就是这样,里面填的东西和find里是差很少的。
用法跟普通的用法一致,直接放栗子:
db.student.aggregate( {$group:{_id:"$sex",count:{$sum:1}}}, {$sort:{age:1}} ) { "_id" : "female", "count" : 2 } { "_id" : "male", "count" : 3 }
若是前面的其余方法都看懂了,这个应该不成问题。就不解释了。
一样跟前面很像,直接放例子:
db.student.aggregate( {$skip:2},{$limit:2} ) { "_id" : ObjectId("5e003f66f197cb08dc74a313"), "name" : "wangzirui", "age" : 22, "sex" : "male" } { "_id" : ObjectId("5e003f8ff197cb08dc74a314"), "name" : "zhuhuan", "age" : 22, "sex" : "female" }
不解释了。
for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}
在数据量特别庞大的时候,寻找数据就会变得慢一点。
因此要针对性的给集合创建索引
db.test.ensureIndex({name:1})
而后这个集合就有两个索引了,以前那个索引叫_id,如今添加了一个域name也做为索引。
关于索引的几个操做: