聲明:這是一份查看指令的文檔而不是教程,對於一些不多用的操作不錄入。
文章目錄
一、系統操作
假設MongoDB路徑爲:E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10
1.1 啓動服務器
E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\bin\mongod.exe --dbpath E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\data
1.2 連接服務器
E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\bin\mongo.exe
E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\bin\mongo.exe localhost:port/db -u user -p password
1.3 安裝服務
需要管理員權限打開cmd
E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\bin\mongod.exe --bind_ip 0.0.0.0 --logpath E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\data\logs\mongodb.log --logappend --dbpath E:\JavaWeb\mongodb-win32-x86_64-2008plus-ssl-4.0.10\data\db --serviceName "MongoDB" --serviceDisplayName "MongoDB" --install
1.4 使用場景
應用特徵 | YES / NO |
---|---|
應用不需要事務及複雜 join 支持 | 必須 Yes |
新應用,需求會變,數據模型無法確定,想快速迭代開發 | ? |
應用需要2000-3000以上的讀寫QPS(更高也可以) | ? |
應用需要TB甚至 PB 級別數據存儲 | ? |
應用發展迅速,需要能快速水平擴展 | ? |
應用要求存儲的數據不丟失 | ? |
應用需要99.999%高可用 | ? |
應用需要大量的地理位置查詢、文本查詢 | ? |
如果上述有1個 Yes,可以考慮 MongoDB,2個及以上的 Yes,選擇 MongoDB 絕不會後悔。
二、 基本操作
2.1 數據類型
2.1.1 浮點數
shell默認使用64位浮點型數值,如下:
db.collection.insert({x:3.1415926})
db.collection.insert({x:3})
2.1.2 整數
我們可以使用NumberInt或者NumberLong表示整數:
db.collection.insert({x:NumberInt(10)})
db.collection.insert({x:NumberLong(12)})
2.1.3 字符串
db.collection.insert({x:"hello MongoDB!"})
2.1.4 正則表達式
正則表達式主要用在查詢裏邊,查詢時我們可以使用正則表達式,語法和JavaScript中正則表達式的語法相同,比如查詢所有key爲x,value以hello開始的文檔且不區分大小寫:
db.collection.find({x:/^(hello)(.[a-zA-Z0-9])+/i})
2.1.5 數組
db.collection.insert({x:[1,2,3,4,new Date()]})
2.1.6 日期
MongoDB支持Date類型的數據,可以直接new一個Date對象:
db.collection.insert({x:new Date()})
2.1.7 內嵌文檔
一個文檔也可以作爲另一個文檔的value:
db.sang_collect.insert({name:"三國演義",author:{name:"羅貫中",age:99}});
2.1.8 ObjectId
我們每次插入一條數據系統都會自動幫我們插入一個_id
鍵,這個鍵的值不可以重複,它可以是任何類型的,我們也可以手動的插入,默認情況下它的數據類型是ObjectId,由於MongoDB在設計之初就是用作分佈式數據庫,所以使用ObjectId可以避免不同數據庫中_id
的重複(如果使用自增的方式在分佈式系統中就會出現重複的_id
的值)。
ObjectId使用12字節的存儲空間,每個字節可以存儲兩個十六進制數字,所以一共可以存儲24個十六進制數字組成的字符串,在這24個字符串中,前8位表示時間戳,接下來6位是一個機器碼,接下來4位表示進程id,最後6位表示計數器。
2.1.9二進制
二進制數據的存儲不能在shell中操作
2.1.10 JS代碼
db.sang_collect.insert({x:function f1(a,b){return a+b;}});
2.2 數據庫操作
2.2.1 創建與切換數據庫
use db:如果數據庫不存在,則創建數據庫,否則切換到指定數據庫。只有在內容插入後纔會真正創建
2.2.2 查看數據庫
show dbs:顯示所有數據的列表。
db :用於查看當前操作的文檔(數據庫)
2.2.3 刪除數據庫
db.dropDatabase():刪除當前數據庫
2.3 集合操作
2.3.1 創建集合
db.createCollection(“collection”, {name, options):創建capped collections
db.runCommand({convertToCapped:“collection”,size:10}):將一個普通集合轉爲一個固定集合
options 可以是如下參數:
字段 | 類型 | 描述 |
---|---|---|
capped | 布爾 | (可選)如果爲 true,則創建固定集合。固定集合是指有着固定大小的集合,當達到最大值時,它會自動覆蓋最早的文檔。 當該值爲 true 時,必須指定 size 參數。 |
autoIndexId | 布爾 | (可選)如爲 true,自動在 _id 字段創建索引。默認爲 false。 |
size | 數值 | (可選)爲固定集合指定一個最大值(以字節計)。 如果 capped 爲 true,也需要指定該字段。 |
max | 數值 | (可選)指定固定集合中包含文檔的最大數量。 |
舉例:db.createCollection(“mycoll”, {capped:true,autoIndexId:true,size:100000,max:1000})
在插入文檔時,MongoDB 首先檢查固定集合的 size 字段,然後檢查 max 字段。
2.3.2 刪除集合
db.collection.drop():刪除集合
2.3.3 查看集合
show tables:查看全部集合
show collections:查看全部集合
2.4 文檔操作
2.4.1 插入文檔
db.collection.insert({x:10}):往集合中插入文檔
2.4.2 更新文檔
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的記錄,會新建一個文檔並插入update的數據,true爲插入,默認是false,不插入。 |
multi | (可選)mongodb 默認是false,只更新找到的第一條記錄,如果這個參數爲true,就把按條件查出來多條記錄全部更新。 |
writeConcern | (可選)拋出異常的級別。 |
save:傳入文檔以替換已有文檔
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
參數 | 說明 |
---|---|
document | 文檔數據。 |
writeConcern | 可選,拋出異常的級別。 |
2.4.3 查看文檔
db.collection.find(query, projection)
參數 | 說明 |
---|---|
query | (可選)使用查詢操作符指定查詢條件 |
projection | (可選)使用投影操作符指定返回的鍵。查詢時返回文檔中所有鍵值, 只需省略該參數即可(默認省略)。 |
舉例:db.collection.find({key1:value1, key2:value2}).pretty(),多個條件用逗號隔開
db.collection.find():查看集合內的文檔
db.collection.find().pretty():格式化查看集合內的文檔
db.collection.find({“title” : {$type : 2}}):獲取 “collection” 集合中 title 爲 String 的數據
db.collection.find({“title” : {$type : ‘string’}}):獲取 “collection” 集合中 title 爲 String 的數據
db.collection.find().limit(number):限制 “collection” 集合讀取的數據記錄條數爲number條
db.collection.find().skip(number):跳過 “collection” 集合的前number條數據記錄
db.collection.find().sort({KEY:1}):對數據進行排序,1 爲升序排列, -1 爲降序排列
db.collection.find({},{x:1}):查找文檔返回指定數據,參數1表示返回某一個字段,0表示不返回某一個字段,當我們設置只返回x的時候,_id
默認還是返回的,如果不想返回_id
,我們可以設置_id
爲0
- 查詢NULL值
db.collection.find({<field>:{exists:true}}):使用$exists判斷該字段是否存在,避免查找到字段不存在的文檔
- 查詢正則表達式
db.collection.find({x:/^(hello)(.[a-zA-Z0-9])+/i}):查詢所有key爲x,value以hello開始的文檔且不區分大小寫
- 查詢數組
{<field>:{$all:[<value>,<value>]}}:查詢包含以上value的文檔
{<field>:[<value>,<value>]}:精確查詢存儲以上value的文檔
{<field>.<num>:<value>}:查詢指定下標num值爲value的數文檔
{<field>:{$size:<num>}}:查詢數組長度爲num的文檔
{},{<field>:{$slice:<num>}}:查詢數組中的前num條數據,整數表示數組中前num個元素,負數表示從後往前數num個元素,也可以使<num>=[<num>,<num>]表示範圍數據
- 查詢嵌套文件
{<field>.<field>:<num>,<field>.<field>:<num>}:可以在查詢使忽視文檔中字段的順序
2.4.4 刪除文檔
db.collection.remove(
<query>,
<justOne>
)
2.6版本後:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
參數 | 說明 |
---|---|
query | (可選)刪除的文檔的條件。 |
justOne | (可選)如果設爲 true 或 1,則只刪除一個文檔,如果不設置該參數,或使用默認值 false,則刪除所有匹配條件的文檔。 |
writeConcern | (可選)拋出異常的級別。 |
舉例:db.collection.remove(document,1)
2.5 算數運算
MongoDB支持簡單的算數運算
三、高級操作
3.1 索引
3.1.1 創建索引
db.collection.createIndex(keys, options): Key 值爲要創建的索引字段,1 升序,-1爲降序。如{“title”:1}。options具體參數後面可查。
db.collection.ensureIndex({:,:}):創建複合索引
db.collection.ensureIndex({:“text”}):創建全文索引
db.collection.ensureIndex({:“2d”}):創建2D索引
db.collection.ensureIndex({:“2dsphere”}):創建2D spere索引s
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引過程會阻塞其它數據庫操作,background可指定以後臺方式創建索引,即增加 “background” 可選參數。 “background” 默認值爲false。 |
unique | Boolean | 建立的索引是否唯一。指定爲true創建唯一索引。默認值爲false. |
name | string | 索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。 |
dropDups | Boolean | 3.0+版本已廢棄。在建立唯一索引時是否刪除重複記錄,指定 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. |
使用 hint():
可以使用 hint 來強制 MongoDB 使用一個指定的索引。
這種方法某些情形下會提升性能。 一個有索引的 collection 並且執行一個多字段的查詢(一些字段已經索引了)。
舉例:
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
3.1.2 查看索引
默認情況下,集合中的_id
字段就是索引
db.collection.getIndexes():查看指定集合中的索引
db.collection.totalIndexSize():查看指定集合中的索引的大小
3.1.3 刪除索引
db.collection.dropIndex(“xIndex”):按名稱刪除索引
db.collection.dropIndexes():刪除所有索引
3.1.4 全文索引
db.collection.ensureIndex({:“text”}):創建全文索引
db.collection.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: text:{search:}}):查詢文檔,value用空格間隔表示包含下一個單詞,用-間隔表示不包含下一個單詞。
db.collection.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: text:{search:}},{score:{$meta:“textScore”}}):查看查詢結果的相似度
3.1.5 地理空間索引
地理空間索引可以分爲兩類:
1、2d索引,可以用來存儲和查找平面上的點。
2、2d sphere索引,可以用來存儲和查找球面上的點。
2d索引
db.collection.ensureIndex({:“2d”}):創建2D索引
db.collection.find({:{maxDistance:10}}):使用maxDistance來設置返回的最遠距離:
db.collection.find({:{KaTeX parse error: Expected '}', got 'EOF' at end of input: geoWithin:{box:[[0,0],[91,1]]}}}):通過box爲矩陣
db.collection.find({:{KaTeX parse error: Expected '}', got 'EOF' at end of input: geoWithin:{center:[[0,0],90]}}}):通過center爲圓
db.collection.find({:{KaTeX parse error: Expected '}', got 'EOF' at end of input: geoWithin:{polygon:[[0,0],[100,0],[100,1],[0,1]]}}}):通過polygon爲多邊形
2d sphere索引
db.collection.ensureIndex({:“2dsphere”}):創建2D spere索引
db.collection.find({location:{KaTeX parse error: Expected '}', got 'EOF' at end of input: within:{geometry:.location}}}):查詢與value區域有交集的
db.collection.find({location:{KaTeX parse error: Expected '}', got 'EOF' at end of input: near:{geometry:.location}}}):查詢在value區域附件的
3.2 聚合
操作:db.collection.aggregate(options)
舉例:db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {$sum : 1}}}])
相當於:select by_user, count(*) from mycol group by by_user
聚合表達式:
表達式 | 描述 | 實例 |
---|---|---|
$sum | 計算總和。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {likes"}}}]) |
$avg | 計算平均值 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {likes"}}}]) |
$min | 獲取集合中所有文檔對應值得最小值。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {likes"}}}]) |
$max | 獲取集合中所有文檔對應值得最大值。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {likes"}}}]) |
$push | 在結果文檔中插入值到一個數組中。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {url"}}}]) |
$addToSet | 在結果文檔中插入值到一個數組中,但不創建副本。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {url"}}}]) |
$first | 根據資源文檔的排序獲取第一個文檔數據。 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", first_url : {url"}}}]) |
$last | 根據資源文檔的排序獲取最後一個文檔數據 | db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", last_url : {url"}}}]) |
管道操作:
- $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
- match使用MongoDB的標準查詢操作。
- $limit:用來限制MongoDB聚合管道返回的文檔數。
- $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
- $unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
- $group:將集合中的文檔分組,可用於統計結果。
- $sort:將輸入文檔排序後輸出。
- $geoNear:輸出接近某一地理位置的有序文檔。
3.3 查看執行計劃
3.3.1 explains
explain():用在查詢語句中,只適用於find()。explain()的用法和sort()、limit()用法差不多,不同的是explain()必須放在最後面。
舉例:db.collection.find({:}).explain()
返回結果:
1、queryPlanner:查詢計劃
2、serverInfo:MongoDB服務的一些信息
其中各個參數的含義爲:
參數 | 含義 |
---|---|
plannerVersion | 查詢計劃版本 |
namespace | 要查詢的集合 |
indexFilterSet | 是否使用索引 |
parsedQuery | 查詢條件,此處爲x=1 |
winningPlan | 最佳執行計劃 |
stage | 查詢方式,常見的有COLLSCAN/全表掃描、IXSCAN/索引掃描、FETCH/根據索引去檢索文檔、SHARD_MERGE/合併分片結果、IDHACK/針對_id進行查詢 |
filter | 過濾條件 |
direction | 搜索方向 |
rejectedPlans | 拒絕的執行計劃 |
serverInfo | MongoDB服務器信息 |
添加參數:
除了默認的explain()之外,explain還支持輸入參數
舉例:explain(“queryPlanner”)
參數類型:
1、queryPlanner:默認參數,與不添加無異
2、executionStats:會返回最佳執行計劃的一些統計信息,多了**“executionStats”:{…}**
3、allPlansExecution:獲取所有的執行計劃
其中executionStats中包含的參數有:
參數 | 含義 |
---|---|
executionSuccess | 是否執行成功 |
nReturned | 返回的結果數 |
executionTimeMillis | 執行耗時 |
totalKeysExamined | 索引掃描次數 |
totalDocsExamined | 文檔掃描次數 |
executionStages | 這個分類下描述執行的狀態 |
stage | 掃描方式,具體可選值與上文的相同 |
nReturned | 查詢結果數量 |
executionTimeMillisEstimate | 預估耗時 |
works | 工作單元數,一個查詢會分解成小的工作單元 |
advanced | 優先返回的結果數 |
docsExamined | 文檔檢查數目,與totalDocsExamined一致 |
3.3.2 Profiling
explains只適用find方法,對於一些聚合查詢之類的查詢方法就無法統計耗時時間了。可以使用profiling來記錄耗時。
開啓Profiling的方法:
1、 直接在啓動參數裏直接進行設置。啓動MongoDB時加上–profile=級別
2、在客戶端調用db.setProfilingLevel(級別)
命令來實時配置。
之後便可以通過db.getProfilingLevel()
命令來獲取當前的Profile級別。
Profiling
一共分爲3個級別:
0
- 不開啓。
1
- 記錄慢命令 (默認爲>100ms)
3
- 記錄所有命令
設置慢命令:
1、直接在啓動參數裏直接進行設置。啓動MongoDB時加上–slowms=毫秒數
2、db.setProfilingLevel( level , slowms)
db.system.profile.find():查詢profile記錄
profile 部分字段解釋:
op
:操作類型
ns
:被查的集合
commond
:命令的內容
docsExamined
:掃描文檔數
nreturned
:返回記錄數
millis
:耗時時間,單位毫秒
ts
:命令執行時間
responseLength
:返回內容長度
3.4 MapReduce
var map=function(){emit(this.<field>,this.<value>)}
var reduce=function(key,value){return Array.sum(value)}
var options={out:"totalPrice"}
db.collection.mapReduce(map,reduce,options);
db.totalPrice.find()
emit函數主要用來實現分組,接收兩個參數,第一個參數表示分組的字段,第二個參數表示要統計的數據。
reduce來做具體的數據處理操作,接收兩個參數,對應emit方法的兩個參數,這裏使用了Array中的sum函數對price字段進行自加處理。
options中定義了將結果輸出的集合。
屆時我們將在這個集合中去查詢數據,默認情況下,這個集合即使在數據庫重啓後也會保留,並且保留集合中的數據。
runCommand實現:
也可以利用runCommand命令來執行MapReduce。格式如下:
db.runCommand(
{
mapReduce: <collection>,
map: <function>,
reduce: <function>,
finalize: <function>,
out: <output>,
query: <document>,
sort: <document>,
limit: <number>,
scope: <document>,
jsMode: <boolean>,
verbose: <boolean>,
bypassDocumentValidation: <boolean>,
collation: <document>
}
)
含義如下:
參數 | 含義 |
---|---|
mapReduce | 表示要操作的集合 |
map | map函數 |
reduce | reduce函數 |
finalize | 最終處理函數 |
out | 輸出的集合 |
query | 對結果進行過濾 |
sort | 對結果排序 |
limit | 返回的結果數 |
scope | 設置參數值,在這裏設置的值在map、reduce、finalize函數中可見 |
jsMode | 是否將map執行的中間數據由javascript對象轉換成BSON對象,默認爲false |
verbose | 是否顯示詳細的時間統計信息 |
bypassDocumentValidation | 是否繞過文檔驗證 |
collation | 其他一些校對 |
3.5 集羣(副本集)
3.5.1 單臺服務器配置副本集
創建數據存儲目錄:
mkdir /data/db
啓動Mongo Shell:
# —nodb表示啓動時不連接任何數據庫
mongo --nodb
創建一個副本集:
replicaSet=new ReplSetTest({nodes:3})
在創建的日誌中,我們可以看到三個實例的端口號,我這裏分別是20000、20001、20002,此時我們的副本集創建好了,但是並未啓動,接下來執行如下命令啓動三個mongodb實例:
replicaSet.startSet()
再執行如下命令配置複製功能:
replicaSet.initiate()
這樣環境基本就配好了,此時當前的shell不要關閉,我們重新打開一個Linux命令窗口,執行如下命令:
mongo 192.168.248.128:20000/collection
表示連接端口爲20000的那個實例中的collection數據庫,連接成功後,我們可以執行如下命令查看當前實例的身份,如下:
db.isMaster()
返回的數據很多,其中有一條是"ismaster" : true
,表示這是一個主節點,此時我們再分別打開兩個Linux窗口,分別執行如下兩條命令,進入另外兩個節點:
mongo 192.168.248.128:20001/collection
mongo 192.168.248.128:20002/collection
連接成功之後,依然可以通過db.isMaster()
命令來查看備份節點的身份,我們發現此時"ismaster" : false
,表示這是一個備份節點,此時我們可以先做個簡單的測試了,此時我在主節點(端口爲20000)那個節點上寫一個文檔,寫完之後,我們看看其他副本集成員上是否有我剛纔的寫的文檔的副本,執行命令順序如下:
主節點寫入數據:
db.collect1.insert({x:"hahaha"})
任意一個副本節點,先執行如下命令表示可以從備份節點讀取數據:
db.setSlaveOk()
然後再在備份節點中執行如下命令讀取數據:
db.collect1.find()
此時,我們發現數據已經備份成功了。
如果此時我們嘗試向備份節點中直接寫入文檔,會發現寫入失敗,這裏需要注意備份節點中的數據都是備份來的,不可以直接寫入,想寫入,除非等它的身份轉爲主節點纔可以。
此時,我們嘗試通過如下命令關閉主節點:
use admin
db.shutdownServer()
然後查看兩個備份節點的db.isMaster(),發現有一個備份節點自動上位成爲了主節點。
最後如果想關閉副本集,可以回到第一個shell命令行中,輸入如下命令:
replicaSet.stopSet()
3.5.2 多臺服務器配置副本集
首先準備好三臺裝好了MongoDB的服務器,地址分別如下:
192.168.248.128
192.168.248.135
192.168.248.136
修改每臺服務器的配置文件mongodb.conf,添加replSet=rs,表示副本集的名稱,修改後的配置文件內容如下:
dbpath=/opt/mongodb/db
logpath=/opt/mongodb/logs/mongodb.log
port=27017
fork=true
replSet=rs
修改完成之後,分別啓動三臺服務器上的MongoDB,啓動成功之後,連接上任意一臺的shell,連接成功之後,先定義配置文件,如下:
config={_id:"rs",members:[{_id:0,host:"192.168.248.128:27017"},{_id:1,host:"192.168.248.135:27017"},{_id:2,host:"192.168.248.136:27017"}]}
id後面跟着的是副本集的名稱,也就是我們在mongodb.conf中定義的名稱,後面三個是副本集的成員,定義好之後,再執行如下命令初始化副本集:
rs.initiate(config)
初始化成功之後,我們就可以通過rs.status()來查看副本集的狀態,也可以看到每個服務器的角色,部分日誌內容如下:
{
"members" : [
{
"_id" : 0,
"name" : "192.168.248.128:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY"
},
{
"_id" : 1,
"name" : "192.168.248.135:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"syncingTo" : "192.168.248.128:27017"
}
]
}
我們可以看到每臺服務器的角色,有primary,也有secondary,secondary上還註明了從哪個服務器上同步數據。
3.5.3 副本集成員添加刪除
我們可以利用如下命令刪除一個副本集成員:
rs.remove('ip:port')
上面的命令執行完成後,我們可以通過rs.status()命令來查看是否刪除成功:
rs.status()
也可以通過如下命令來爲副本集添加一個成員:
rs.add('ip:port')
我們可以在添加節點時指定優先級:
rs.add({_id:0,host:'ip:port',priority:2})
也可以爲已有的節點設置優先級:
config=rs.config()
config.members[0].priority=99
rs.reconfig(config)
當然,副本集也是可以更新的,使用reconfig命令即可,如下:
首先定義config,如下:
config={_id:"rs",members:[{_id:0,host:"ip"},{_id:1,host:"ip"}]}
然後執行更新操作:
rs.reconfig(config)
我們也可以利用config=rs.config()獲取原始的config文件,然後進行修改,修改之後再執行 rs.reconfig(config),如下:
config=rs.config()
config.members[0].host="192.168.248.136"
rs.reconfig(config)
3.5.4 選舉仲裁者
向副本集中添加仲裁者:
rs.addArb('192.168.248.128:27017')
config=rs.config()
config.members[2]={_id:2,host:'ip',arbiterOnly:true}
rs.reconfig(config)
3.5.5 數據同步方式
db.getCollection(‘oplog.rs’).stats()
四、操作符
4.1 條件操作符
操作 | 格式 | 範例 | 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 |
4.2 邏輯操作符
操作 | 格式 | 示例 |
---|---|---|
或者 | $or | {$or: [{<key>: <value>}, {<key>:<value>}]} |
A或B包含 | $in | {<key>:{$in:[<value>,<value>]}} |
都不包含 | $nin | {<key>:{$nin:[<value>,<value>]}} |
類型查找 | $type | {<key>:{$type:<value>}} |
取反 | $not | {<key>:{$not:<value>}} |
A和B包含 | $all | {<key>:{$all:[<value>,<value>]}} |
同時比較 | $elemMatch | {<key>:{$elemMatch:{$lt:<num>,$gt:<num>}}} |
4.3 類型操作符
類型 | 數字 | 備註 |
---|---|---|
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 |
- 類型操作
var newObject = ObjectId():定義唯一主鍵
newObject.getTimestamp():查看文檔的時間戳
newObject.str:ObjectId轉字符串輸出
newObject.toString():ObjectId轉字符串輸出
4.4 修改器
4.4.1 更新操作
$set:可以用來修改一個字段的值,如果這個字段不存在,則創建它。
{$set:{<field>:<value>}}
$unset:可以用來刪除一個字段。
{$unset:{<field>:<value>}}
inc只能用來操作數字,不能用來操作null、布爾等。
{$inc:{<field>:<value>}}
$sort:用以排序,-1表示降序,1表示升序。
{$sort:{score:-1}}
4.1.2 數組更新操作
$push:可以向已有數組末尾追加元素,要是不存在就創建一個數組。
{$push:{<field>:<value>}}
$addToSet:可以向已有數組末尾追加其不存在的元素,要是不存在就創建一個數組。
{$addToSet:{<field>:<value>}}
addToSet操作符和$push操作符:
{$addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{$push: { <field>: { $each: [ <value1>, <value2> ... ] } } }
$slice:固定數組的長度,假設我固定數組的長度爲5,如果數組中的元素不足5個,則全部保留,如果數組中的元素超過5個,則只會保留最新的5個,
{$push:{<field>:{<value>,$slice:5}}}
$pop:可以用來刪除數組中的數據,1表示從數組的末尾刪除一條數據,-1表示從數組的開頭刪除一條數據。
{$pop:{<field>:1}}
$pull:按條件刪除數組中的某個元素
{$pull:{<field>:"1"}}
4.5 算數操作符
操作 | 格式 | 示例 |
---|---|---|
增加 | $add | {$add: [<value>,<value>...]} |
減去 | $subtract | {$subtract:[<value>,<value>...]} |
相乘 | $multiply | {$multiply:[<value>,<value>...]} |
求商 | $divide | {$divide:[<value>,<value>...]} |
求模 | $mod | {$mod:[<value>,<value>...]} |
五 Java Driver
5.1 Maven依賴
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.5.0</version>
</dependency>
5.2 連接操作
5.2.1 建立連接
首先需要一個MongoClient:
MongoClient client = new MongoClient("127.0.0.1", 27017);
然後通過如下方式獲取一個數據庫,如果要獲取的數據庫本身就存在,直接獲取到,不存在MongoDB會自動創建:
MongoDatabase database = client.getDatabase("test");
然後通過如下方式獲取一個名爲collection的集合,這個集合存在的話就直接獲取到,不存在的話MongoDB會自動創建出來,如下:
MongoCollection<Document> collection = sang.getCollection("collection");
5.2.2 登錄操作
// 登錄地址
ServerAddress serverAddress = new ServerAddress("127.0.0.1", 27017);
// MongoCredential是一個憑證,第一個參數爲用戶名,第二個參數是要在哪個數據庫中驗證,第三個參數是密碼的char數組,
List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
MongoCredential mc = MongoCredential.createScramSha1Credential("root","test","123456".toCharArray());
credentialsList.add(mc);
MongoClient client = new MongoClient(serverAddress,credentialsList);
5.2.3 設置超時
// 登錄地址
ServerAddress serverAddress = new ServerAddress("192.168.248.128", 27017);
// 身份憑證
List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
MongoCredential mc = MongoCredential.createScramSha1Credential("rwuser","sang","123".toCharArray());
credentialsList.add(mc);
// 配置參數設置
MongoClientOptions options = MongoClientOptions.builder()
//設置連接超時時間爲10s
.connectTimeout(1000*10)
//設置最長等待時間爲10s
.maxWaitTime(1000*10)
.build();
// 建立連接
MongoClient client = new MongoClient(serverAddress,credentialsList,options);
5.2 文檔操作
5.2.1 增加文檔
單條數據:
Document document = new Document();
document.append("name", "三國演義").append("author", "羅貫中");
collection.insertOne(document);
多條數據:
List<Document> documentList = new ArrayList<Document>();
Document d1 = new Document();
d1.append("name", "三國演義").append("author", "羅貫中");
documentList.add(d1);
Document d2 = new Document();
d2.append("name", "紅樓夢").append("author", "曹雪芹");
documentList.add(d2);
collection.insertMany(documentList);
5.2.2 修改文檔
修改查到的第一條數據:
collection.updateOne(Filters.eq("author", "羅貫中"), new Document("$set", new Document("name", "三國演義123")));
修改查到的所有數據:
collection.updateMany(Filters.eq("author", "羅貫中"), new Document("$set", new Document("name", "三國演義456")));
5.2.3 刪除文檔
刪除查到的一條數據:
c.deleteOne(Filters.eq("author", "羅貫中"));
刪除查到的所有數據:
c.deleteMany(Filters.eq("author", "羅貫中"));
5.2.4 查看文檔
直接查詢所有文檔:
FindIterable<Document> documents = collection.find();
for (Document value : documents) {
System.out.println(value);
}
按照條件查詢:
FindIterable<Document> documents = collection.find(Filters.eq("author", "羅貫中"));
for (Document value : documents) {
System.out.println(value);
}