MongoDB非關係型資料庫開發手冊
- 2019 年 10 月 3 日
- 筆記
一:NoSql資料庫
什麼是NoSQL?
NoSQL,指的是非關係型的資料庫。NoSQL有時也稱作Not Only SQL的縮寫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。
NoSQL用於超大規模數據的存儲。(例如Google或Facebook每天為他們的用戶收集萬億比特的數據)。這些類型的數據存儲不需要固定的模式,無需多餘操作就可以橫向擴展。
為什麼使用NoSQL ?
今天我們可以通過第三方平台(如:Google,Facebook等)可以很容易的訪問和抓取數據。用戶的個人資訊,社交網路,地理位置,用戶生成的數據和用戶操作日誌已經成倍的增加。我們如果要對這些用戶數據進行挖掘,那SQL資料庫已經不適合這些應用了, NoSQL資料庫的發展也卻能很好的處理這些大的數據。
CAP定理(CAP theorem)
在電腦科學中, CAP定理(CAP theorem), 又被稱作 布魯爾定理(Brewer’s theorem), 它指出對於一個分散式計算系統來說,不可能同時滿足以下三點:
- 一致性(Consistency) (所有節點在同一時間具有相同的數據)
- 可用性(Availability) (保證每個請求不管成功或者失敗都有響應)
- 分隔容忍(Partition tolerance) (系統中任意資訊的丟失或失敗不會影響系統的繼續運作)
CAP理論的核心是:一個分散式系統不可能同時很好的滿足一致性,可用性和分區容錯性這三個需求,最多只能同時較好的滿足兩個。
因此,根據 CAP 原理將 NoSQL 資料庫分成了滿足 CA 原則、滿足 CP 原則和滿足 AP 原則三 大類:
- CA – 單點集群,滿足一致性,可用性的系統,通常在可擴展性上不太強大。
- CP – 滿足一致性,分區容忍性的系統,通常性能不是特別高。
- AP – 滿足可用性,分區容忍性的系統,通常可能對一致性要求低一些。
NoSQL的優點/缺點
優點:
- – 高可擴展性
- – 分散式計算
- – 低成本
- – 架構的靈活性,半結構化數據
- – 沒有複雜的關係
缺點:
- – 沒有標準化
- – 有限的查詢功能(到目前為止)
- – 最終一致是不直觀的程式
NoSQL 資料庫分類
類型 | 部分代表 | 特點 |
---|---|---|
列存儲 | Hbase Cassandra Hypertable | 顧名思義,是按列存儲數據的。最大的特點是方便存儲結構化和半結構化數據,方便做數據壓縮,對針對某一列或者某幾列的查詢有非常大的IO優勢。 |
文檔存儲 | MongoDB CouchDB | 文檔存儲一般用類似json的格式存儲,存儲的內容是文檔型的。這樣也就有有機會對某些欄位建立索引,實現關係資料庫的某些功能。 |
key-value存儲 | Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis | 可以通過key快速查詢到其value。一般來說,存儲不管value的格式,照單全收。(Redis包含了其他功能) |
圖存儲 | Neo4J FlockDB | 圖形關係的最佳存儲。使用傳統關係資料庫來解決的話性能低下,而且設計使用不方便。 |
對象存儲 | db4o Versant | 通過類似面向對象語言的語法操作資料庫,通過對象的方式存取數據。 |
xml資料庫 | Berkeley DB XMLBaseX | 高效的存儲XML數據,並支援XML的內部查詢語法,比如XQuery,Xpath。 |
二:MongoDB
MongoDB 是由C++語言編寫的,是一個基於分散式文件存儲的開源資料庫系統。
在高負載的情況下,添加更多的節點,可以保證伺服器性能。
MongoDB 旨在為WEB應用提供可擴展的高性能數據存儲解決方案。
MongoDB 將數據存儲為一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔類似於 JSON 對象。欄位值可以包含其他文檔,數組及文檔數組。
適用場景
1.數據快取
2.JSON格式的數據
3.高伸縮性場景
4.弱事務類型業務
Mongodb更多適合於大數據量,高並發,弱事務的互聯網應用,其內置的水平擴展機制提供了從幾百萬到十億級別的數據處理能力,可以很好的滿足Web2.0和移動互聯網應用的數據存儲要求。
應用情況
版本說明
比如:3.1.0 第二個數是奇數為測試版,偶數為穩定版。
Linux下安裝
創建目錄
mkdir mongodb
下載
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.0.tgz
解壓
tar -zxvf mongodb-linux-x86_64-4.0.0.tgz
查看路徑
[root@ZhuJi mongodb-linux-x86_64-4.0.0]# pwd /usr/local/mongodb/mongodb-linux-x86_64-4.0.0
MongoDB 的可執行文件位於 bin 目錄下,所以可以將其添加到 PATH 路徑中:
注意export命令只對此次會話有效。
export PATH=/usr/local/mongodb/mongodb-linux-x86_64-4.0.0/bin:$PATH
創建資料庫目錄
MongoDB的數據存儲在data目錄的db目錄下,但是這個目錄在安裝過程不會自動創建,所以你需要手動創建data目錄,並在data目錄中創建db目錄。
mkdir data
創建日誌目錄
mkdir log
啟動程式:mongod命令
mongod --dbpath data --logpath log/mongod.log -logappend --fork
你也可以把啟動命令寫入start.sh文件
echo "mongod --dbpath data --logpath log/mongod.log -logappend --fork" >> start.sh
登錄資料庫
mongo
示例:
$ ./mongo MongoDB shell version: 3.0.6 connecting to: test >
小結
創建文件夾:data,用來存儲資料庫的數據文件。
創建文件夾:log,用來存儲資料庫的日誌文件。
創建文件夾:bin,用來存儲資料庫的可執行文件。
創建文件夾:conf,用來存儲資料庫的配置文件。
三:概念
MongoDB概念解析
不管我們學習什麼資料庫都應該學習其中的基礎概念,在mongodb中基本的概念是文檔、集合、資料庫,下面我們挨個介紹。
下表將幫助您更容易理解Mongo中的一些概念:
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 資料庫 |
table | collection | 資料庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據欄位/域 |
index | index | 索引 |
table joins | 表連接,MongoDB不支援 | |
primary key | primary key | 主鍵,MongoDB自動將_id欄位設置為主鍵 |
MongoDB 數據類型
下表為MongoDB中常用的幾種數據類型。
數據類型 | 描述 |
---|---|
String | 字元串。存儲數據常用的數據類型。在 MongoDB 中,UTF-8 編碼的字元串才是合法的。 |
Integer | 整型數值。用於存儲數值。根據你所採用的伺服器,可分為 32 位或 64 位。 |
Boolean | 布爾值。用於存儲布爾值(真/假)。 |
Double | 雙精度浮點值。用於存儲浮點值。 |
Min/Max keys | 將一個值與 BSON(二進位的 JSON)元素的最低值和最高值相對比。 |
Array | 用於將數組或列表或多個值存儲為一個鍵。 |
Timestamp | 時間戳。記錄文檔修改或添加的具體時間。 |
Object | 用於內嵌文檔。 |
Null | 用於創建空值。 |
Symbol | 符號。該數據類型基本上等同於字元串類型,但不同的是,它一般用於採用特殊符號類型的語言。 |
Date | 日期時間。用 UNIX 時間格式來存儲當前日期或時間。你可以指定自己的日期時間:創建 Date 對象,傳入年月日資訊。 |
Object ID | 對象 ID。用於創建文檔的 ID。 |
Binary Data | 二進位數據。用於存儲二進位數據。 |
Code | 程式碼類型。用於在文檔中存儲 JavaScript 程式碼。 |
Regular expression | 正則表達式類型。用於存儲正則表達式。 |
四:命令
資料庫命令
"show dbs" 命令可以顯示所有數據的列表。
執行 "db" 命令可以顯示當前資料庫對象或集合。
運行"use"命令,可以連接到一個指定的資料庫。
> show dbs; admin 0.000GB config 0.000GB local 0.000GB > db test > use local switched to db local > db local >
有一些資料庫名是保留的,可以直接訪問這些有特殊作用的資料庫。
- admin: 從許可權的角度來看,這是"root"資料庫。要是將一個用戶添加到這個資料庫,這個用戶自動繼承所有資料庫的許可權。一些特定的伺服器端命令也只能從這個資料庫運行,比如列出所有的資料庫或者關閉伺服器。
- local: 這個數據永遠不會被複制,可以用來存儲限於本地單台伺服器的任意集合
- config: 當Mongo用於分片設置時,config資料庫在內部使用,用於保存分片的相關資訊。
創建資料庫
如果資料庫不存在,則創建資料庫,否則切換到指定資料庫。
use demo
插入一條數據
db.demo.insert({"name":"菜鳥先飛"})
展示資料庫
show dbs
MongoDB 中默認的資料庫為 test,如果你沒有創建新的資料庫,集合將存放在 test 資料庫中。
刪除資料庫
MongoDB 刪除資料庫的語法格式如下:
db.dropDatabase()
刪除當前資料庫,默認為 test,你可以使用 db 命令查看當前資料庫名。
刪除集合
集合刪除語法格式如下:
db.collection.drop()
實例
> show collections demo > db.demo.drop() true > show collections
創建集合
語法格式:
db.createCollection(name, options)
參數說明:
- name: 要創建的集合名稱
- options: 可選參數, 指定有關記憶體大小及索引的選項
options 可以是如下參數:
欄位 | 類型 | 描述 |
---|---|---|
capped | 布爾 | (可選)如果為 true,則創建固定集合。固定集合是指有著固定大小的集合,當達到最大值時,它會自動覆蓋最早的文檔。 當該值為 true 時,必須指定 size 參數。 |
autoIndexId | 布爾 | (可選)如為 true,自動在 _id 欄位創建索引。默認為 false。 |
size | 數值 | (可選)為固定集合指定一個最大值(以位元組計)。 如果 capped 為 true,也需要指定該欄位。 |
max | 數值 | (可選)指定固定集合中包含文檔的最大數量。 |
在插入文檔時,MongoDB 首先檢查固定集合的 size 欄位,然後檢查 max 欄位。
實例
不帶參
db.createCollection("runoob")
帶參
db.createCollection("mycol", {capped : true, autoIndexId : true, size : 6142800, max : 10000})
在 MongoDB 中,你不需要創建集合。當你插入一些文檔時,MongoDB 會自動創建集合。
db.mycol2.insert({"name" : "菜鳥教程"})
查看已有集合
show collections
或者
show tables
插入文檔
MongoDB 使用 insert() 或 save() 方法向集合中插入文檔,語法如下:
db.COLLECTION_NAME.insert(document)
實例
以下文檔可以存儲在 MongoDB 的 runoob 資料庫 的 col 集合中:
db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一個 Nosql 資料庫', by: '菜鳥教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
以上實例中 col 是我們的集合名,如果該集合不在該資料庫中, MongoDB 會自動創建該集合併插入文檔。
查看已插入文檔:
db.col.find()
列印
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
我們也可以將數據定義為一個變數,如下所示:
document=({title: 'MongoDB 教程', description: 'MongoDB 是一個 Nosql 資料庫', by: '教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 });
執行插入操作:
db.col.insert(document)
更新文檔
update() 方法
update() 方法用於更新已存在的文檔。語法格式如下:
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } )
參數說明:
- query : update的查詢條件,類似sql update查詢內where後面的。
- update : update的對象和一些更新的操作符(如$,$inc…)等,也可以理解為sql update查詢內set後面的
- upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入。
- multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。
- writeConcern :可選,拋出異常的級別。
實例
我們在集合 col 中插入如下數據:
db.col.insert({ title: 'MongoDB 教程', description: 'MongoDB 是一個 Nosql 資料庫', by: '教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
接著我們通過 update() 方法來更新標題(title):
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
以上語句只會修改第一條發現的文檔,如果你要修改多條相同的文檔,則需要設置 multi 參數為 true。
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
更多實例
只更新第一條記錄:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
只添加第一條:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
全部添加加進去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
只更新第一條記錄:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
在3.2版本開始,MongoDB提供以下更新集合文檔的方法:
- db.collection.updateOne() 向指定集合更新單個文檔
- db.collection.updateMany() 向指定集合更新多個文檔
save() 方法
save() 方法通過傳入的文檔來替換已有文檔。語法格式如下:
db.collection.save( <document>, { writeConcern: <document> } )
參數說明:
- document : 文檔數據。
- writeConcern :可選,拋出異常的級別。
實例
以下實例中我們替換了 _id 為 56064f89ade2f21f36b03136 的文檔數據:
db.col.save({ "_id" : ObjectId("5b4df2a53e3e9f9874019902"), "title" : "MongoDB", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "Runoob", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "NoSQL" ], "likes" : 110 })
拋出異常的級別
- WriteConcern.NONE:沒有異常拋出
- WriteConcern.NORMAL:僅拋出網路錯誤異常,沒有伺服器錯誤異常
- WriteConcern.SAFE:拋出網路錯誤異常、伺服器錯誤異常;並等待伺服器完成寫操作。
- WriteConcern.MAJORITY: 拋出網路錯誤異常、伺服器錯誤異常;並等待一個主伺服器完成寫操作。
- WriteConcern.FSYNC_SAFE: 拋出網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器將數據刷新到磁碟。
- WriteConcern.JOURNAL_SAFE:拋出網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器提交到磁碟的日誌文件。
- WriteConcern.REPLICAS_SAFE:拋出網路錯誤異常、伺服器錯誤異常;等待至少2台伺服器完成寫操作。
刪除文檔
語法
remove() 方法的基本語法格式如下所示:
db.collection.remove( <query>, <justOne> )
如果你的 MongoDB 是 2.6 版本以後的,語法格式如下:
db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document> } )
參數說明:
- query :(可選)刪除的文檔的條件。
- justOne : (可選)如果設為 true 或 1,則只刪除一個文檔。
- writeConcern :(可選)拋出異常的級別。
實例
以下文檔我們執行兩次插入操作:
db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一個 Nosql 資料庫', by: '菜鳥教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
使用 find() 函數查詢數據:
db.col.find()
接下來我們移除 title 為 ‘MongoDB 教程’ 的文檔:
db.col.remove({'title':'MongoDB 教程'})
如果你想刪除所有數據,可以使用以下方式(類似常規 SQL 的 truncate 命令):
db.col.remove({})
推薦使用delete()
remove() 方法已經過時了,現在官方推薦使用 deleteOne() 和 deleteMany() 方法。
如刪除集合下全部文檔:
db.col.deleteMany({})
刪除 status 等於 A 的全部文檔:
db.col.deleteMany({ status : "A" })
刪除 status 等於 D 的一個文檔:
db.col.deleteOne( { status: "D" } )
查詢文檔
MongoDB 查詢文檔使用 find() 方法。
find() 方法以非結構化的方式來顯示所有文檔。
語法
MongoDB 查詢數據的語法格式如下:
db.collection.find(query, projection)
- query :可選,使用查詢操作符指定查詢條件
- projection :可選,使用投影操作符指定返回的鍵。查詢時返迴文檔中所有鍵值, 只需省略該參數即可(默認省略)。
如果你需要以易讀的方式來讀取數據,可以使用 pretty() 方法,語法格式如下:
db.col.find().pretty()
pretty() 方法以格式化的方式來顯示所有文檔。
實例
以下實例我們查詢了集合 col 中的數據:
db.col.find().pretty() { "_id" : ObjectId("56063f17ade2f21f36b03133"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
除了 find() 方法之外,還有一個 findOne() 方法,它只返回一個文檔。
MongoDB 與 RDBMS Where 語句比較
如果你熟悉常規的 SQL 數據,通過下表可以更好的理解 MongoDB 的條件語句查詢:
操作 | 格式 | 範例 | RDBMS中的類似語句 |
---|---|---|---|
等於 | {<key>:<value> } |
db.col.find({"by":"菜鳥教程"}).pretty() |
where by = '菜鳥教程' |
小於 | {<key>:{$lt:<value>}} |
db.col.find({"likes":{$lt:50}}).pretty() |
where likes < 50 |
小於或等於 | {<key>:{$lte:<value>}} |
db.col.find({"likes":{$lte:50}}).pretty() |
where likes <= 50 |
大於 | {<key>:{$gt:<value>}} |
db.col.find({"likes":{$gt:50}}).pretty() |
where likes > 50 |
大於或等於 | {<key>:{$gte:<value>}} |
db.col.find({"likes":{$gte:50}}).pretty() |
where likes >= 50 |
不等於 | {<key>:{$ne:<value>}} |
db.col.find({"likes":{$ne:50}}).pretty() |
where likes != 50 |
AND 條件
MongoDB 的 find() 方法可以傳入多個鍵(key),每個鍵(key)以逗號隔開,即常規 SQL 的 AND 條件。
語法格式如下:
db.col.find({key1:value1, key2:value2}).pretty()
類似於 WHERE 語句:WHERE by=’教程’ AND title=’MongoDB 教程’
OR 條件
MongoDB OR 條件語句使用了關鍵字 $or,語法格式如下:
db.col.find( { $or: [ {key1: value1}, {key2:value2} ] } ).pretty()
實例
以下實例中,我們演示了查詢鍵 by 值為 教程 或鍵 title 值為 MongoDB 教程 的文檔。
db.col.find({$or:[{"by":"教程"},{"title": "MongoDB 教程"}]}).pretty()
AND 和 OR 聯合使用
以下實例演示了 AND 和 OR 聯合使用,類似常規 SQL 語句為: ‘where likes>50 AND (by = ‘教程’ OR title = ‘MongoDB 教程’)’
db.col.find({"likes": {$gt:50}, $or: [{"by": "教程"},{"title": "MongoDB 教程"}]}).pretty()
projection 參數的使用方法
db.collection.find(query, projection)
若不指定 projection,則默認返回所有鍵,指定 projection 格式如下,有兩種模式
db.collection.find(query, {title: 1, by: 1}) // inclusion模式 指定返回的鍵,不返回其他鍵 db.collection.find(query, {title: 0, by: 0}) // exclusion模式 指定不返回的鍵,返回其他鍵
_id 鍵默認返回,需要主動指定 _id:0 才會隱藏
實例
db.col.find({"likes": {$gt:50}}, {_id:0}).pretty()
返回沒有_id的結果:
{ "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
兩種模式不可混用(因為這樣的話無法推斷其他鍵是否應返回)
db.collection.find(query, {title: 1, by: 0}) // 錯誤
只能全1或全0,除了在inclusion模式時可以指定_id為0
db.collection.find(query, {_id:0, title: 1, by: 1}) // 正確
條件操作符
描述
條件操作符用於比較兩個表達式並從mongoDB集合中獲取數據。
在本章節中,我們將討論如何在MongoDB中使用條件操作符。
MongoDB中條件操作符有:
- (>) 大於 –
$gt
- (<) 小於 –
$lt
- (>=) 大於等於 –
$gte
- (<= ) 小於等於 –
$lte
(>) 大於操作符 – $gt
如果你想獲取 "col" 集合中 "likes" 大於 100 的數據,你可以使用以下命令:
db.col.find({"likes" : {$gt : 100}})
類似於SQL語句:
Select * from col where likes > 100;
(<) 和 (>) 查詢 – $lt 和 $gt
如果你想獲取"col"集合中 "likes" 大於100,小於 200 的數據,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
類似於SQL語句:
Select * from col where likes>100 AND likes<200;
$type 操作符
MongoDB 中可以使用的類型如下表所示:
類型 | 數字 | 備註 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已廢棄。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1 . |
Max key | 127 |
實例
如果想獲取 "col" 集合中 title 為 String 的數據,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
Limit() 方法
如果你需要在MongoDB中讀取指定數量的數據記錄,可以使用MongoDB的Limit方法,limit()方法接受一個數字參數,該參數指定從MongoDB中讀取的記錄條數。
語法
limit()方法基本語法如下所示:
db.COLLECTION_NAME.find().limit(NUMBER)
Skip() 方法
我們除了可以使用limit()方法來讀取指定數量的數據外,還可以使用skip()方法來跳過指定數量的數據,skip方法同樣接受一個數字參數作為跳過的記錄條數。
語法
skip() 方法腳本語法格式如下:
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
實例**
以下實例只會顯示第二條文檔數據
db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
排序
sort() 方法
在 MongoDB 中使用 sort() 方法對數據進行排序,sort() 方法可以通過參數指定排序的欄位,並使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而 -1 是用於降序排列。
語法
sort()方法基本語法如下所示:
>db.COLLECTION_NAME.find().sort({KEY:1})
索引
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文件並選取那些符合查詢條件的記錄。
這種掃描全集合的查詢效率是非常低的,特別在處理大量的數據時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的性能是非常致命的。
索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中,索引是對資料庫表中一列或多列的值進行排序的一種結構
createIndex() 方法
MongoDB使用 createIndex() 方法來創建索引。
注意在 3.0.0 版本前創建索引方法為 db.collection.ensureIndex(),之後的版本使用了 db.collection.createIndex() 方法,ensureIndex() 還能用,但只是 createIndex() 的別名。
語法
createIndex()方法基本語法格式如下所示:
db.collection.createIndex(keys, options)
語法中 Key 值為你要創建的索引欄位,1 為指定按升序創建索引,如果你想按降序來創建索引指定為 -1 即可。
實例
db.col.createIndex({"title":1})
createIndex() 方法中你也可以設置使用多個欄位創建索引(關係型資料庫中稱作複合索引)。
db.col.createIndex({"title":1,"description":-1})
createIndex() 接收可選參數,可選參數列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引過程會阻塞其它資料庫操作,background可指定以後台方式創建索引,即增加 "background" 可選參數。 "background" 默認值為false。 |
unique | Boolean | 建立的索引是否唯一。指定為true創建唯一索引。默認值為false. |
name | string | 索引的名稱。如果未指定,MongoDB的通過連接索引的欄位名和排序順序生成一個索引名稱。 |
dropDups | Boolean | 在建立唯一索引時是否刪除重複記錄,指定 true 創建唯一索引。默認值為 false. |
sparse | Boolean | 對文檔中不存在的欄位數據不啟用索引;這個參數需要特別注意,如果設置為true的話,在索引欄位中不會查詢出不包含對應欄位的文檔.。默認值為 false. |
expireAfterSeconds | integer | 指定一個以秒為單位的數值,完成 TTL設定,設定集合的生存時間。 |
v | index version | 索引的版本號。默認的索引版本取決於mongod創建索引時運行的版本。 |
weights | document | 索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引欄位的得分權重。 |
default_language | string | 對於文本索引,該參數決定了停用詞及詞幹和詞器的規則的列表。 默認為英語 |
language_override | string | 對於文本索引,該參數指定了包含在文檔中的欄位名,語言覆蓋默認的language,默認值為 language. |
實例
在後台創建索引:
db.values.createIndex({open: 1, close: 1}, {background: true})
通過在創建索引時加 background:true 的選項,讓創建工作在後台執行
聚合
MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點類似sql語句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
語法
aggregate() 方法的基本語法格式如下所示:
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
管道的概念
管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的參數。
MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操作是可以重複的。
表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。
這裡我們介紹一下聚合框架中常用的幾個操作:
- $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
- $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。
- $limit:用來限制MongoDB聚合管道返回的文檔數。
- $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
- $unwind:將文檔中的某一個數組類型欄位拆分成多條,每條包含數組中的一個值。
- $group:將集合中的文檔分組,可用於統計結果。
- $sort:將輸入文檔排序後輸出。
- $geoNear:輸出接近某一地理位置的有序文檔。
管道操作符實例
1、$project實例
db.article.aggregate( { $project : { title : 1 , author : 1 , }} );
這樣的話結果中就只還有_id,tilte和author三個欄位了,默認情況下_id欄位是被包含的,如果要想不包含_id話可以這樣:
db.article.aggregate( { $project : { _id : 0 , title : 1 , author : 1 }});
2.$match實例
db.articles.aggregate( [ { $match : { score : { $gt : 70, $lte : 90 } } }, { $group: { _id: null, count: { $sum: 1 } } } ] );
$match用於獲取分數大於70小於或等於90記錄,然後將符合條件的記錄送到下一階段$group管道操作符進行處理。
3.$skip實例
db.article.aggregate( { $skip : 5 });
經過$skip管道操作符處理後,前五個文檔被"過濾"掉。
數據備份
在Mongodb中我們使用mongodump命令來備份MongoDB數據。該命令可以導出所有數據到指定目錄中。
mongodump命令可以通過參數指定導出的數據量級轉存的伺服器。
語法
mongodump命令腳本語法如下:
mongodump -h dbhost -d dbname -o dbdirectory
-
-h:
MongDB所在伺服器地址,例如:127.0.0.1,當然也可以指定埠號:127.0.0.1:27017
-
-d:
需要備份的資料庫實例,例如:test
-
-o:
備份的數據存放位置,例如:c:datadump,當然該目錄需要提前建立,在備份完成後,系統自動在dump目錄下建立一個test目錄,這個目錄裡面存放該資料庫實例的備份數據。
實例
在本地使用 27017 啟動你的mongod服務。打開命令提示符窗口,進入MongoDB安裝目錄的bin目錄輸入命令mongodump:
mongodump
數據恢復
mongodb使用 mongorestore 命令來恢復備份的數據。
語法
mongorestore命令腳本語法如下:
mongorestore -h <hostname><:port> -d dbname <path>
-
–host <:port>, -h <:port>:
MongoDB所在伺服器地址,默認為: localhost:27017
-
–db , -d :
需要恢復的資料庫實例,例如:test,當然這個名稱也可以和備份時候的不一樣,比如test2
-
–drop:
恢復的時候,先刪除當前數據,然後恢復備份的數據。就是說,恢復後,備份後添加修改的數據都會被刪除,慎用哦!
-
<path>
:mongorestore 最後的一個參數,設置備份數據所在位置,例如:c:datadumptest。
你不能同時指定
<path>
和 –dir 選項,–dir也可以設置備份目錄。 -
–dir:
指定備份的目錄
你不能同時指定
<path>
和 –dir 選項。
接下來我們執行以下命令:
mongorestore
監控
在你已經安裝部署並允許MongoDB服務後,你必須要了解MongoDB的運行情況,並查看MongoDB的性能。這樣在大流量得情況下可以很好的應對並保證MongoDB正常運作。
MongoDB中提供了mongostat 和 mongotop 兩個命令來監控MongoDB的運行情況。
mongostat 命令
mongostat是mongodb自帶的狀態檢測工具,在命令行下使用。它會間隔固定時間獲取mongodb的當前運行狀態,並輸出。如果你發現資料庫突然變慢或者有其他問題的話,你第一手的操作就考慮採用mongostat來查看mongo的狀態。
啟動你的Mongod服務,進入到你安裝的MongoDB目錄下的bin目錄, 然後輸入mongostat命令,如下所示:
mongostat
mongotop 命令
mongotop也是mongodb下的一個內置工具,mongotop提供了一個方法,用來跟蹤一個MongoDB的實例,查看哪些大量的時間花費在讀取和寫入數據。 mongotop提供每個集合的水平的統計數據。默認情況下,mongotop返回值的每一秒。
啟動你的Mongod服務,進入到你安裝的MongoDB目錄下的bin目錄, 然後輸入mongotop命令,如下所示:
mongotop
輸出結果欄位說明:
-
ns:
包含資料庫命名空間,後者結合了資料庫名稱和集合。
-
db:
包含資料庫的名稱。名為 . 的資料庫針對全局鎖定,而非特定資料庫。
-
total:
mongod花費的時間工作在這個命名空間提供總額。
-
read:
提供了大量的時間,這mongod花費在執行讀操作,在此命名空間。
-
write:
提供這個命名空間進行寫操作,這mongod花了大量的時間。