MongoDB非關係型資料庫開發手冊
一:NoSql資料庫
什麼是NoSQL?
NoSQL,指的是非關係型的資料庫。NoSQL有時也稱作Not Only SQL的縮寫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱。
NoSQL用於超大規模資料的儲存。(例如谷歌或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:\data\dump,當然該目錄需要提前建立,在備份完成後,系統自動在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:\data\dump\test。
你不能同時指定
<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花了大量的時間。