mongodb 基礎入門教程

算是學習下來精煉的筆記,但願對你們有幫助。若是有問題歡迎你們指正。javascript

0.概述

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與之對應的就是數組

  • 數據庫
  • 集合
  • 文檔

1.brew安裝

不推薦用brew,由於如今mongodb閉源了,brew裏已經搜索不到mongodb,不過仍是能夠用brew安裝的,這篇就不寫了。服務器

2.官網下載

直接去官網下載一個zip,解壓完放到usr/local/裏(control+shift+。能夠顯示隱藏文件夾),更名爲mongodb。數據結構

而後添加一個環境變量就能夠用了

$ export PATH=/usr/local/mongodb/bin:$PATH

這樣就添加好了,反正就是如今能夠用了。

能夠用mongo來測試是否安裝好了,若是都弄好了應該會彈出版本。

3.建立data/db文件夾

接下來就是新建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也能夠。

4.開啓服務建立客戶端

啓動服務:

sudo mount -uw /

sudo mongod

啓動客戶端:

mongo

5.命令

5.1 db操做

  • 顯示數據庫
    • show dbs
  • 切換數據庫,沒有就新建一個
    • use admin
  • 顯示你在哪一個數據庫裏
    • Db
  • 刪除當前你use的那個數據庫
    • db.dropDatebase()
  • 新建數據庫
    • use 數據庫名字
    • 建完了show dbs不會馬上顯示,由於剛纔新建的數據庫裏面沒有數據。因此顯示不出來。

5.2 collection操做

  • 顯示這個數據庫中有什麼集合
    • show collections
  • 新建集合,在use 一個數據庫的狀況下
    • db.createCollections(name,options)
    • 而後show dbs如今能夠看到use的數據庫了
  • 刪除集合 ,在如今這個Use的數據庫的狀況下
    • db.你想要的collectionname.drop()
    • 而後就刪掉了

5.3 document操做

collectionname代指相對應的collcetion名字(mysql裏叫表,Mongodb裏叫collection,都是一個數據庫裏的一種結構) 如今操做的不是表也不是集合,而是集合裏的一個數據結構叫作document,文檔,文檔至關於mysql裏的一個記錄行。

  • 往collection里加數據,直接新建document
    • db.collectionname.insert({"name":"wangzirui"})
    • 增長多條要在insert的多個對象的外面加一箇中括號,表示這是一個對象數組。
    • db.collectionname.insert([{name:"wangzirui"},{name:"laoli"}])
  • 查看collection裏的數據
    • db.collectionname.find()
  • Save,在_id同樣的狀況下能夠不報錯,而後直接覆蓋掉剛纔重複Id的內容。
    • db.collectionsname.save({_id:1001,name:"laowang",age:22})
  • 更新document數據
    • db.collectionname.update({當前數據},{替換數據},{配置項})
    • db.collectionname.update({name:"laotie"},{name:"ergou"})
    • 這樣會刪除其餘內容,只存在一個name :ergou 因此要加$set保留其餘的參數
    • db.collectionname.update({name:"laotie"},{$set:{name:"ergou"}})
    • 配置項里加{Multi:true}加一個這個的話可讓多個name:"laotie"一塊兒改
    • db.collectionname.update({name:"laotie"},{$set:{name:"ergou"}},{multi:true})
  • 刪除document內容,若是不加第二個參數,默認是把集合裏的符合第一條的都刪掉。
    • Db.collectionname.remove({name:"laotie"},{justOne:true})

5.4 document 查詢

通過上面的講述,能瞭解到一點,基於database來查詢collections裏的數據都是經過db.collcetion_name.方法 來進行操做的,同理。對document的查詢,咱們以前也在查看collection時用過,他就是find()方法。

find裏面能夠加參數,不加的話就是現實collection裏全部的document。

  • find()方法裏能夠加條件,例如db.collectionname.find({age:18})
    • 若是一行一行的話很差看,能夠再db.collectionname.find({age:18})後面加.pretty()
  • 比較運算符
    • less than 小於 $lt db.collection_name.find(age:{$lt:18})
    • less than equal 小於等於 $lte
    • Geater than 大於 $gt
    • $gte 大於等於
    • $ne 不等於
  • 取範圍內的 $in
    • $in:[10,20,30]
    • db.collection_name.find({age:{$in:[10,20,30]}})
  • 並操做
    • db.collection_name.find(age:18,name:"laotie")
  • 或操做
    • db.collection_name.find({$or:[{age:18},{name:"laotie"}]}
  • 正則
    • db.collection_name.find({age:/^1/})或者db.collection_name.find({age:$regex:"^1"})
  • 限制和跳過,通常用於分頁
    • limit(2)
    • skip(2)
  • 投影

    • 好比說find({這裏放具體參數},{這裏放投影})
    • db.collection_name.find({age:{$lt:18}},{_id:0,age:1}) 這樣只會顯示每一個對象裏面只有一個age選項了
    • 注意,若是投影裏不加_id的選項的話 ,默認是自動顯示的。只能給_id設置 0。若是別的字段不想讓他顯示直接不在裏面加。其餘的想要顯示的話直接把屬性加進去就好了。
  • 經過Js函數來篩選數據

    • $where:

    • db.collection_name.find({$where:function(){

      Return age>10}})

  • 根據某個字段排序

    • sort
    • db.collection_name.find().sort({age:1}) 若是降序的話要帶-1
  • 計數

    • count()

    • 直接在查詢出來的後面加上就能夠顯示了

    • db.collection_name.find({$where:function(){

      Return age>10}}).count()

  • 去重

    • db.student.distinct("name",{"age" : 18})
    • 這樣能夠直接把name同樣還有age爲18的都給去重

6.備份和恢復

6.1備份

直接在終端輸入,不要在mongodb的客戶端輸入

mongodump -h hostname -d dbname -o dbdirectory

-h 服務器地址,能夠指定端口號。本機能夠不填

-d 具體Mongodb下哪一個數據庫

-o 你想保存到本地的什麼地方

例如本機 下在termainal直接輸入 mongodump -d laotie -o wenjianjia

而後就把 laotie這個數據庫保存到Users/wangzirui/wenjianjia這個文件夾裏了

6.2恢復

一樣直接在終端輸入

Mongorestore -h hostname -d dbname --dir

-h 服務器地址,能夠指定端口號。本機能夠不填

-d 你想讓這個數據庫叫什麼,不必定是原名

-Dir 這個備份文件在哪裏

7.聚合

aggregate,就是一個管道,相似中間件或者是函數的鏈式調用。最終導出想要的數據。

7.1group

首先放一個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:

另外講一個$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去重:

$group不止能夠添加一個分組條件,也能夠添加多個分組條件,若是把每一個條件都對應文檔的域,那麼就至關於去重操做。

> db.student.aggregate({
     $group:{_id:{name:"$name",sex:"$sex",age:"$age"}}
})

而後接下來用別的通道來進行下一步的操做就能夠了。可是接下來的操做要用到的屬性就是$_id.name相似的。由於咱們去重時把屬性都給了叫_id的域。

7.2$project

重構輸出結構,也就是在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代替。具體不舉例子了,沒什麼大用。

7.4 $match

聽名字就知道是過濾用的,雖然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裏是差很少的。

7.5 $sort

用法跟普通的用法一致,直接放栗子:

db.student.aggregate(
    {$group:{_id:"$sex",count:{$sum:1}}},
  {$sort:{age:1}}
)

{ "_id" : "female", "count" : 2 }
{ "_id" : "male", "count" : 3 }

若是前面的其餘方法都看懂了,這個應該不成問題。就不解釋了。

7.6 $limit,skip

一樣跟前面很像,直接放例子:

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" }

不解釋了。

8.建立索引

for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}

在數據量特別龐大的時候,尋找數據就會變得慢一點。

因此要針對性的給集合創建索引

db.test.ensureIndex({name:1})

而後這個集合就有兩個索引了,以前那個索引叫_id,如今添加了一個域name也做爲索引。

關於索引的幾個操做:

  • 建立惟一索引
    • db.test.ensureIndex({name:1},{uniqe:true})
  • 創建聯合索引
    • db.test.ensureIndex({name:1},{age:1})
  • 查看當前集合的索引
    • db.test.getIndexes()
  • 刪除索引
    • db.t1.dropIndex("索引名")
相關文章
相關標籤/搜索