- MongoDB特點
1.支持特別查詢
- 在MongoDB中,可以通過字段,範圍查詢進行搜索,並且還支持正則表達式搜索。
2.索引
- 可以索引文檔中的任何字段。
3.複製
- MongoDB支持主從複製。主機可以執行讀寫操作,從機從主機複製數據,只能用於讀取或備份(不寫入)
4.複製數據
- MongoDB可以在多台服務器上運行。 複製數據以保持系統正常運行,並在硬件故障的情況下保持其運行狀態。
5.負載均衡
- 由於數據放在碎片中,因此具有自動負載平衡配置。
6.支持映射縮減和聚合工具
7.使用JavaScript而不是Procedure
8.它是一個用C++編寫的無模式數據庫
9.提供高性能
10.輕鬆存儲任何大小的文件,而不會使您的堆棧複雜化
11.在故障的情況下易於管理
12.它還支持:
- 具有動態模式的JSON數據模型
- 自動分片用於水平可擴展性
- 內置複製高可用性
二、安裝配置
1.下載安裝
在Windows上安裝 MongoDB,首先打開: http://www.mongodb.org/downloads 下載最新版本的
2.MongoDB配置(mongodb.conf)
#數據庫路徑
dbpath=C:\Program Files\MongoDB\Server\3.4\data
#日誌輸出文件路徑
logpath=C:\Program Files\MongoDB\Server\3.4\logs\mongo.log
#錯誤日誌採用追加模式
logappend=true
#啓用日誌文件,默認啓用
journal=true
#這個選項可以過濾掉一些無用的日誌信息,若需要調試使用請設置為false
quiet=true
#端口號 默認為27017
port=27017
3.Windows服務配置(mongodb.bat)
--啓動MongoDB服務
mongod --config "C:\Program Files\MongoDB\Server\3.4\mongo.conf"
--添加啓動服務
mongod --config "C:\Program Files\MongoDB\Server\3.4\mongo.conf" --install --serviceName "MongoDB"
--添加帶權限認證的
mongod --config "C:\Program Files\MongoDB\Server\3.4\mongo.conf" --auth --install --serviceName "MongoDB"
--啓動服務
net start MongoDB
--刪除服務
mongod.exe --remove --serviceName "MongoDB"
sc delete MongoDB
--
4.用户權限配置(啓動後執行mongo.exe)命令
use admin
--創建用户
db.createUser({user:"admin",pwd:"admin",roles:["userAdminAnyDatabase","dbAdminAnyDatabase","root"]})
--創建角色
db.createRole({
"role": "mongostatRole",
"privileges": [
{
"resource": {
"cluster": true
},
"actions": [
"serverStatus"
]
}
],
"roles": []
})
--授權用户角色
db.grantRolesToUser("admin",[{role: "mongostatRole",db: "admin"}])
--創建其他用户
db.createUser({
"user": "dba",
"pwd": "dba",
"db" : "ucloudlink",
"roles": [
{
"role" : "readWrite",
"db" : "ucloudlink"
},
{
"role" : "readWrite",
"db" : "newdb"
}
]
})
三、MongoDB數據類型
MongoDB支持許多數據類型。 其中一些是 -
- 字符串 - 這是用於存儲數據的最常用的數據類型。MongoDB中的字符串必須為UTF-8。
- 整型 - 此類型用於存儲數值。 整數可以是32位或64位,具體取決於服務器。
- 布爾類型 - 此類型用於存儲布爾值(true / false)值。
- 雙精度浮點數 - 此類型用於存儲浮點值。
- 最小/最大鍵 - 此類型用於將值與最小和最大BSON元素進行比較。
- 數組 - 此類型用於將數組或列表或多個值存儲到一個鍵中。
- 時間戳 - ctimestamp,當文檔被修改或添加時,可以方便地進行錄製。
- 對象 - 此數據類型用於嵌入式文檔。
- Null - 此類型用於存儲Null值。
- 符號 - 該數據類型與字符串相同; 但是,通常保留用於使用特定符號類型的語言。
- 日期 - 此數據類型用於以UNIX時間格式存儲當前日期或時間。您可以通過創建日期對象並將日,月,年的日期進行指定自己需要的日期時間。
- 對象ID - 此數據類型用於存儲文檔的ID。
- 二進制數據 - 此數據類型用於存儲二進制數據。
- 代碼 - 此數據類型用於將JavaScript代碼存儲到文檔中。
- 正則表達式 - 此數據類型用於存儲正則表達式。
四、使用MongoDB數據庫
1、登錄數據庫
Mongo
User admin
db.auth(“admin”,”admin”);
show dbs
--帶認證的登錄
mongo --port 27017 -u "admin" -p "admin" --authenticationDatabase "admin"
2、創建數據庫
user newdb
3、刪除數據庫
db.dropDatabase()
4、創建集合
MongoDB 的 db.createCollection(name,options) 方法用於在MongoDB 中創建集合。
語法
createCollection()命令的基本語法如下 -
db.createCollection(name, options)
在命令中,name 是要創建的集合的名稱。 options是一個文檔,用於指定集合的配置。
|
參數 |
類型 |
描述 |
|
name |
String |
要創建的集合的名稱 |
|
options |
Document |
(可選)指定有關內存大小和索引的選項 |
options參數是可選的,因此只需要指定集合的名稱。 以下是可以使用的選項列表:
|
字段 |
類型 |
描述 |
|
capped |
Boolean |
(可選)如果為true,則啓用封閉的集合。上限集合是固定大小的集合,它在達到其最大大小時自動覆蓋其最舊的條目。 如果指定true,則還需要指定size參數。 |
|
autoIndexId |
Boolean |
(可選)如果為true,則在_id字段上自動創建索引。默認值為false。 |
|
size |
數字 |
(可選)指定上限集合的最大大小(以字節為單位)。 如果capped為true,那麼還需要指定此字段的值。 |
|
max |
數字 |
(可選)指定上限集合中允許的最大文檔數。 |
在插入文檔時,MongoDB首先檢查上限集合capped字段的大小,然後檢查max字段。
5、刪除集合
MongoDB 的 db.collection.drop() 用於從數據庫中刪除集合。
6、聚合
6.1、count() 方法
db.article.count();
db.article.count({by_user:"Maxsu"})
6.2、distinct()方法
db.article.distinct('by_user')
db.runCommand({"distinct":"article","key":"by_user"})
6.3、aggregate()方法
db.article.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
6.4、group()方法
7、索引
索引支持查詢的有效地提高效率。沒有索引,MongoDB必須掃描集合的每個文檔,以選擇與查詢語句匹配的文檔。這種掃描效率很低,需要 MongoDB 處理大量的數據。
索引是特殊的數據結構,以易於遍歷的形式存儲數據集的一小部分。 索引存儲特定字段或一組字段的值,按照索引中指定的字段值排序。
ensureIndex()方法
要創建索引,需要使用MongoDB的ensureIndex()方法。
語法
ensureIndex()方法的基本語法如下 -
>db.COLLECTION_NAME.ensureIndex({KEY:1})
這裏的key是要在其上創建索引的字段的名稱,1是升序。 要按降序創建索引,需要使用-1。
示例
>db.mycol.ensureIndex({"title":1})
Shell
在ensureIndex()方法中,可以傳遞多個字段,以在多個字段上創建索引。
>db.mycol.ensureIndex({"title":1,"description":-1})
ensureIndex()方法也接受選項列表(可選)。 以下是列表 -
|
參數 |
類型 |
描述 |
|
|
|
在後台構建索引,以便構建索引不會阻止其他數據庫活動,則指定 |
|
|
|
創建一個唯一的索引,使得集合不會接受索引鍵或鍵匹配索引中現有值的文檔的插入。 指定 |
|
|
|
索引的名稱。如果未指定,則MongoDB通過連接索引字段的名稱和排序順序來生成索引名稱。 |
|
|
|
在可能有重複項的字段上創建唯一索引。MongoDB僅索引第一次出現的鍵,並從集合中刪除包含該鍵的後續出現的所有文檔。指定 |
|
|
|
如果為 |
|
|
|
指定一個值(以秒為單位)作為 |
|
|
索引版本 |
索引版本號。默認索引版本取決於創建索引時運行的MongoDB的版本。 |
|
|
文檔 |
權重是從 |
|
|
|
對於文本索引,確定停止詞列表的語言以及句柄和分詞器的規則。 默認值為英文。 |
|
|
|
對於文本索引,要指定文檔中包含覆蓋默認語言的字段名稱。默認值為 |
五、MongoDB 監控
1、連接MongoDB
mongo --port 27017 -u "admin" -p "admin" --authenticationDatabase "admin"
2、mongostat
此命令檢查所有運行的mongod實例的狀態,並返回數據庫操作的計數器。 這些計數器包括插入,查詢,更新,刪除和遊標。 命令還顯示遇到頁面錯誤,並顯示鎖定百分比。這可以用來監控內存不足,寫入容量或出現性能問題。
Mongostat 5 --port 27017 -u "admin" -p "admin" --authenticationDatabase "admin"
3、mongotop
此命令跟蹤並報告基於集合的 MongoDB 實例的讀寫活動。 默認情況下,mongotop會在每秒鐘內返回信息,但是可相應地更改信息。應該檢查此讀寫活動是否符合您的應用意圖,並且要一次對數據庫發出太多的寫入操作,從磁盤讀取的頻率太高,或者超出了工作集合大小。
mongotop 5 --port 27017 -u "admin" -p "admin" --authenticationDatabase "admin"
六、MongoDB關聯關係
MongoDB中的關係表示各個文檔在邏輯上的相互關聯。關係可以通過嵌入式和引用方法建模。 這種關係可以是1:1,1:N,N:1或N:N。
假設有一種情況:要存儲用户的地址。一個用户可以擁有多個地址,這就是1:N關係。
以下是用户(users)文檔示例的文檔結構 -
{
"_id":10999110,
"name": "Maxsu",
"contact": "13888990021",
"dob": "1992-10-11"
}
以下是地址(address)文檔的示例文檔結構 -
{
"_id":12200,
"building": "Hainan Building NO.2100",
"pincode": 571100,
"city": "Haikou",
"province": "Hainan"
}
1、嵌入式關係建模
在嵌入式方法中,我們將地址(address)文檔嵌入到用户(users)文檔中。
{
"_id": 21000100,
"contact": "13800138000",
"dob": "1991-11-11",
"name": "Maxsu",
"address": [
{
"building": "Hainan Building NO.2100",
"pincode": 571100,
"city": "Haikou",
"province": "Hainan"
},
{
"building": "Sanya Building NO.2100",
"pincode": 572200,
"city": "Sanya",
"province": "Hainan"
},
]
}
該方法將所有相關數據保存在單個文檔中,這使得檢索和維護更容易。可以使用單個查詢來在整個文檔檢索,例如 -
> db.users.findOne({"name":"Maxsu"},{"address":1, "name":1})
請注意,缺點是如果嵌入式文檔的大小如果不斷增長,可能會影響讀/寫性能。
2、建模參考關係
這是設計規範化關係的方法。 在這種方法中,用户和地址文件將分別維護,但用户文檔將包含一個將引用地址文檔的id字段的字段。
{
"_id":ObjectId("52ffc33321332111sdfaf"),
"contact": "13800138000",
"dob": "1991-11-11",
"name": "Maxsu",
"address_ids": [
ObjectId("123123"),
ObjectId("123412")
]
}
如上所示,用户文檔包含對應地址的ObjectId的數組字段address_ids。 使用這些ObjectIds,我們可以從那裏查詢地址文件並獲取地址詳細信息。 使用這種方法,需要兩個查詢:首先從用户文檔獲取address_ids字段,然後從地址集中獲取這些地址。
>var result = db.users.findOne({"name":"Maxsu"},{"address_ids":1})
>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})
七、MongoDB數據庫引用
DBRefs
考慮一個示例場景,在這個場景中將使用DBRefs而不是手動引用,設計有一個數據庫中將不同類型的地址(家庭,辦公室,郵件等)存儲在不同的集合(address_home,address_office,address_mailing等)中。 現在,當用户集合的文檔引用地址時,還需要根據地址類型指定要查找的集合。 在這種情況下,文檔引用了多個集合中的文檔,則應該使用DBRefs。
使用DBRefs
DBRefs中有三個字段 -
$ref- 此字段指定引用文檔的集合$id- 此字段指定引用文檔的_id字段$db- 這是一個可選字段,幷包含引用文檔所在的數據庫的名稱
假設一個具有DBRef字段address的示例用户文檔,如代碼片段所示 -
{
"_id":ObjectId("348362491fjaskdlf2314"),
"address": {
"$ref": "address_home",
"$id": ObjectId("sfaafdf4137832149fssa"),
"$db": "ucloudlink"},
"contact": "13800138000",
"dob": "1991-12-12",
"name": "Maxsu"
}
這裏的 DBRef 字段 address指定引用的地址文件位於ucloudlink數據庫中的address_home集合中,其ID為sfaafdf4137832149fssa。
以下代碼由$ref參數(在示例中為address_home)指定的集合中動態地查找ID為DBRef中的$id參數指定的文檔。
>var user = db.users.findOne({"name":"Maxsu"})
>var dbRef = user.address
>db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
以上代碼返回address_home集合中存在的以下address文檔中
{
"_id" : ObjectId("sfaafdf4137832149fssa"),
"building" : "Hainan Apt No.2100",
"pincode" : 571100,
"city" : "Haikou",
"province" : "Hainan"
}
八、Java連接MongoDB操作
九、Mongodb集羣搭建
Mongodb的三種集羣方式的搭建:Replica Set / Sharding / Master-Slaver
1、Replica Set(副本集)
簡單來説就是集羣當中包含了多份數據,保證主節點掛掉了,備節點能繼續提供數據服務,提供的前提就是數據需要和主節點一致。如下圖:
Mongodb(M)表示主節點,Mongodb(S)表示備節點,Mongodb(A)表示仲裁節點。主備節點存儲數據,仲裁節點不存儲數據。客户端同時連接主節點與備節點,不連接仲裁節點。
默認設置下,主節點提供所有增刪查改服務,備節點不提供任何服務。但是可以通過設置使備節點提供查詢服務,這樣就可以減少主節點的壓力,當客户端進行數據查詢時,請求自動轉到備節點上。這個設置叫做Read Preference Modes,同時Java客户端提供了簡單的配置方式,可以不必直接對數據庫進行操作。
仲裁節點是一種特殊的節點,它本身並不存儲數據,主要的作用是決定哪一個備節點在主節點掛掉之後提升為主節點,所以客户端不需要連接此節點。這裏雖然只有一個備節點,但是仍然需要一個仲裁節點來提升備節點級別。我開始也不相信必須要有仲裁節點,但是自己也試過沒仲裁節點的話,主節點掛了備節點還是備節點,所以咱們還是需要它的。
接下來Windows環境創建一個Replica Set(副本集):
- 建立配置文件
C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs0.conf
C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs1.conf
C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs2.conf
1.2、創建複製集服務
sc.exe create OpenXLive.MongoDB_Ad.Shard_a0 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs0.conf\"" DisplayName= "rs_a0_Service" start= "auto"
sc.exe create OpenXLive.MongoDB_Ad.Shard_a1 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs1.conf\"" DisplayName= "rs_a1_Service" start= "auto"
sc.exe create OpenXLive.MongoDB_Ad.Shard_a2 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\a\rs2.conf\"" DisplayName= "rs_a2_Service" start= "auto"
1.3、配置及初始化 Replica Sets
初始化配置,使上面的配置生效
call mongo.exe 127.0.0.1:10000/admin
--一個簡單的複製集最少包括三個節點。 1.primary 2. secondary,3.arbiter節點
cfg={_id: 'rs_a', members:[{_id:0,host:'127.0.0.1:10000',priority:2}, {_id:1,host:'127.0.0.1:10001',priority:1},{_id:2,host:'127.0.0.1:10002',arbiterOnly:true}]};
rs.initiate(cfg);
查看複製集狀態
rs.conf();
rs.status();
在primary節點上查看複製集狀態:
rs.isMaster()
`2、分片集羣架構
分片集羣主要有mongos路由進程、配置服務器、複製集組成的分片集合組成。 如下圖:
- 碎片(Shards) - 碎片用於存儲數據。它們提供高可用性和數據一致性。 在生產環境中,每個分片是一個單獨的副本集。
- 配置服務器(Config Servers) - 配置服務器存儲集羣的元數據。 該數據包含集羣的數據集與分片的映射。查詢路由器使用此元數據將操作定位到特定的分片。 在生產環境中,分片集羣正好有
3個配置服務器。 - 查詢路由器(Query Routers) - 查詢路由器基本上是 mongo 實例,與客户端應用程序的接口和直接操作到適當的分片。 查詢路由器處理並將操作定向到碎片,然後將結果返回給客户端。 分片集羣可以包含多個查詢路由器來分割客户端請求負載。 客户端向一個查詢路由器發送請求。 一般來説,分片集羣有許多查詢路由器。
分片集羣上一個分片(shard) 就是一個複製集。 當然也可以是一個單個Mongod實例。在集羣中一般用複製集。保證一個分片不會故障。如果一個分片出現故障。整個集羣就掛了。因為每一個分片上保留數據的一部分。所有分片的綜合才是所有數據。所以我們應該保證每個分片上數據的完整性和穩定性至關重要。
Mongos和配置服務器是輕量級進程。是不會保存數據的。 配置服務器只保存分片的一些狀態信息。 所以整個讀取集羣的過程為: 訪問Mongos-查詢配置服務器,根據配置服務器要求寫入或讀取那些分片服務器進行讀取數據。
2.1、創建副本集
創建副本集b、c
2.2、創建配置服務
sc.exe create OpenXLive.MongoDB_Ad.Shard_cfg0 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\configsvr\cfgserver_0.conf"" DisplayName= "rs_cfg0_Service" start= "auto"
sc.exe create OpenXLive.MongoDB_Ad.Shard_cfg1 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\configsvr\cfgserver_1.conf"" DisplayName= "rs_cfg1_Service" start= "auto"
sc.exe create OpenXLive.MongoDB_Ad.Shard_cfg2 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\configsvr\cfgserver_2.conf"" DisplayName= "rs_cfg2_Service" start= "auto"
call mongo.exe 127.0.0.1:40000/admin
cfg={_id: 'configs', members:[{_id:0,host:'127.0.0.1:40000'}, {_id:1,host:'127.0.0.1:40001'},{_id:2,host:'127.0.0.1:40002'}]};
rs.initiate(cfg);
2.3、創建路由服務
sc.exe create rs_mongosr_Service1 binPath= "\"C:\Program Files\MongoDB\Server\3.4\bin\mongos.exe\" --service --config=\"C:\Program Files\MongoDB\Server\3.4\cluster\config\mongos\cfg_mongos.conf"" DisplayName= "rs_mongosr_Service1" start= "auto"
直接啓動
mongos --config "C:\Program Files\MongoDB\Server\3.4\cluster\config\mongos\cfg_mongos.conf"
call mongo.exe 127.0.0.1:50000/admin
db.runCommand({addshard:"rs_a/127.0.0.1:10000,127.0.0.1:10001",name:"ShardSetA"})
db.runCommand({addshard:"rs_b/127.0.0.1:20000,127.0.0.1:20001",name:"ShardSetB"})
db.runCommand({listshards : 1})
printShardingStatus()
db.runCommand({"enablesharding":"ucloudlink"})
sh.status()
十、MongoDB其他高級特性
1、MongoDB原子操作
2、MongoDB高級索引
3、MongoDB Map Reduce
根據MongoDB文檔的説明,Map-reduce是將大量數據合併為有用的聚合結果的數據處理範例。 MongoDB使用mapReduce命令進行map-reduce操作。MapReduce通常用於處理大型數據集。
MapReduce命令
以下是基本 mapReduce 命令的語法 -
>db.collection.mapReduce(
function() {emit(key,value);}, //map function
function(key,values) {return reduceFunction}, { //reduce function
out: collection,
query: document,
sort: document,
limit: number
}
)
map-reduce函數首先查詢集合,然後將結果文檔映射到發出的鍵值對,然後根據具有多個值的鍵進行減少。
在上面的語法 -
map是一個JavaScript函數,它將一個值與一個鍵映射併發出一個鍵值對;reduce是一個javascript功能,可以減少或分組具有相同鍵的所有文檔;out指定map-reduce查詢結果的位置;query指定選擇文檔的可選選擇條件;sort指定可選的排序條件;limit指定可選的最大文檔數;
使用MapReduce
請考慮存儲用户帖子的以下文檔結構。 該文檔存儲用户的user_name和帖子的狀態(status)。
{
"post_text": "bilin tutorials is an awesome website for tutorials",
"user_name": "maxsu",
"status":"active"
}
現在,我們將在posts集上使用mapReduce函數來選擇所有status的值為active的帖子,並根據user_name分組,然後使用以下代碼對每個用户的帖子數進行計數
>db.posts.mapReduce(
function() { emit(this.user_id,1); },
function(key, values) {return Array.sum(values)}, {
query:{status:"active"},
out:"post_total"
}
)
4、MongoDB文本搜索
5. MongoDB正則表達式
正則表達式在所有的編程語言中經常使用,用於以搜索任何字符串中的模式或單詞。 MongoDB還提供使用$regex運算符的字符串模式匹配的正則表達式的功能。 MongoDB使用PCRE(Perl兼容正則表達式)作為正則表達式語言。
與文本搜索不同,不需要使用任何配置或命令來使用正則表達式。
請考慮以下文檔結構,其中包含post文本及其標籤 -
{
"post_text": "enjoy the mongodb articles on bilin tutorials",
"tags": [
"mongodb",
"bilin"
]
}
使用正則表達式
以下regex查詢搜索包含”bilin“字符串的所有帖子 -
>db.posts.find({post_text:{$regex:"bilin"}})
上面的查詢也可以寫成 -
>db.posts.find({post_text:/bilin/})
使用不區分大小寫的正則表達式
要使搜索不區分大小寫,可指定$options參數的值為$i。 以下命令將尋找具有單詞bilin的字符串,不管其是小寫還是大寫字母 -
>db.posts.find({post_text:{$regex:"bilin", $options:"$i"}})
此查詢返回的結果之一是以下文檔,其中包含大小寫字母的”bilin“單詞 -
{
"_id" : ObjectId("595b99e1f6a6243715b3c316"),
"post_text" : "hey! this is my post on Bilin Bilin",
"tags" : [ "bilin" ]
},
{
"_id" : ObjectId("595b99e1f6a6243715b3c317"),
"post_text" : "hey! this is my post on bilin Bilin",
"tags" : [ "bilin" ]
}
對數組元素使用正則表達式
我們也可以在數組字段上使用正則表達式。當實現標籤的功能時,這尤其重要。 所以,如果要從單詞:tutorial(tutorial,tutorials , tutorialpoint 或 tutorialphp 或 tutorialpython或 tutorialphp)開始搜索所有具有標籤的帖子,可以使用以下代碼 -
> db.posts.find({tags:{$regex:"tutorial"}})
優化正則表達式查詢
- 如果文檔字段創建了索引,則查詢將使用索引值來匹配正則表達式。 與正常表達式掃描整個集合相比,使用索引值使得搜索非常快。
- 如果正則表達式是前綴表達式,則所有匹配都是以某個字符串字符開始。 例如,如果正則表達式是
^tut,則查詢必須僅搜索以tut開頭的那些字符串。
6、MongoDB自動遞增序列