算是學習下來精煉的筆記,但願對你們有幫助。若是有問題歡迎你們指正。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也做爲索引。
關於索引的幾個操做: