標籤:log enable 隨機 包含 nts blog iter 列表 username
mongodb並不具備一些在關係型資料庫中很普遍的功能,如串連和複雜的多行事務。
集合-->文檔-->id id在文檔所屬的集合中是唯一的。
db.help()查看資料庫層級的協助,db.foo.help()查看集合層級的協助。
db.foo.update --不加(),查看函數具體功能,使用參數。
運行指令碼:
mongo --quite host:port/foo scripts.js 串連到指定伺服器的foo資料庫執行指令碼scripts.js檔案。
load()函數從互動模式運行指令碼:load("scripts.js")
db.version() --返回伺服器的版本資訊
db.getCollection("version") --訪問version資料庫:訪問無效集合(只能包含字母、數字、$、_,且不以數字開頭)
x.y=x[‘y‘] --使用此方法訪問無效屬性的集合
var name="#[email protected]!"
db[name].find()
var collections = ["cneter","account","chat"]
for (var i in collections){
print(db.blog[collections[i]]);
}
插入:
db.center,insert({"test":1})
批量插入:
db.center.batchInsert({"test":1},{"test":2},{"test":3})
--將多個文檔插入一個集合,不能在一次請求中將多個文檔插入到多個集合中。
驅動程式允許批量插入的文檔有限制,在失敗之前的所欲資料都成功插入,之後的資料全部丟失。
使用collecyionOnError選項忽略錯誤,並繼續執行後續插入操作。
shell不支援collectionOnError選項,所有驅動程式支援。
mongodb只進行最基本的檢查,插入非法資料很容易,因此,應該只允許信任的源(應用程式伺服器)串連資料庫。
刪除:
db.center.remove() --刪除所有的文檔
db.center.remove({"test":1}) --刪除指定條件的資料
所有的刪除都是永久性的,不可以撤銷、恢複
刪除效率:db.center.remove()<db.center.drop()
"$set":指定一個欄位的值,如果欄位不存在,就建立。
db.cneter.update({"_id":1234},{"$set":{"favorite book":"Hao ma,Hao de"}})
--增加favorite book欄位,修改欄位均可使用"$set"。
db.center.update({"_id":1234},{"$unset":{"favorite":1}}) --將添加的欄位刪除
使用索引值對進行替換,會將整個文檔以新的索引值對覆蓋掉,需要使用¥修飾器來修改索引值對.
"$inc":增加已有鍵的值。
db.center.update({"name":"kasumi","$inc":{"score":50}}) --值為50
db.center.update({"name":"kasumi","$inc":{"score":100}}) --值為150
僅修改數實值型別
"$push":向數組末尾加入一個元素。
"$slice":限制數組所包含的最大長度.
"$sort":繼續排序. --"$slice"和"$sort"需要和"$push"組合使用,且必須使用"$each".
"$addToSet":避免插入時,資料重複。
db.center.update({"_id":1234},"$addToSet":{"email":{"$each":["[email protected]","[email protected]"]}})
刪除:
1)把數組看成隊列或棧,"$pop" --{"$pop":{"key":1}}:從數組末尾刪除一個元素.
2)基於特定的條件刪除元素:"$pull" --會刪除所有的匹配文檔,而不是只刪除一個.
對集合中間的文檔進行修改,若使得文檔尺寸變大,這個文檔將會被移動到集合的尾部。
移動文檔後,會修改集合中的填滿因數,當文檔尺寸增大,移動到最尾部的時候,它原來所佔有的位置就閑置了。
在集合中插入新的文檔,會產生新的填滿因數,若不產生位置的移動時,填滿因數的大小會逐漸減小。
--盡量設定填滿因數的值接近1.
頻繁移動文檔會產生大量空的資料檔案,如果有太多不能重用的空白空間 --Error:was empty,skipping ahead
db.runcommand({"collMod":collectionName,"usePowerOf2Sizes":true}) --提高磁碟複用率.
預設情況下,只更新滿足條件的第一個文檔,需要更改滿足條件的所有文檔,需要將uodate的第四個參數設定為true.
db.runCommand({getLastError:1}) --查詢更新的文檔的數量.
findAndModify --返回修改的資料,進行重新定義.
db.runCommand({"findAndModify":"center","query":{"status":"ready"},"update":{"$set":{"status":"running"}}})
查詢:
find 空查詢文檔({}):匹配集合的全部內容.不指定查詢條件,預設是{}。
指定需要返回的鍵:find或者findone的第二個參數指定想要的鍵。
db.center.find({},{"username":1,"email":1})
索引值為1,則在查詢結果中返回,索引值為0,則在查詢結果中剔除。
限制:傳遞給資料庫查詢文檔的值必須是常量,不能引用文檔中其他鍵的值.
查詢條件:
db.center.find({"age":{"$gte":18,"$lte":30}}) --範圍查詢
$lt:less than $lte:less than and equel $gt:grate than $gte:grate than and equel $ne:not equel
db.center.find({"ticket_no":{"$in":[20,24,45]}}) --or查詢
$nin:not in
$or:對多個鍵的匹配進行匹配
db.cneter.find({"$or":[{"ticket_no":45},{"username":"kasumi"}]})
$mod會將查詢的值除以第一個給定值,若餘數等於第二個給定的值則匹配成功.
db.center.find({"idnum":{"$mod":[5,1]}})
取反操作:db.center.find("idnum":{"$not":{"$mod":[5,1]}})
一個鍵可以有人以多個條件,但是一個鍵不能對應多個更改修飾器.
查詢最佳化工具不會對$and進行最佳化:
db.center.find({"$and":[{"x":{"$lte":1}},{"x":4}]})
db.center.find({"x":{"$lte":1,"$in":[4]}}) --查詢效率更高
特定類型的查詢:
null
db.center.find({"z":{"$in":[null]},"$exists":true}) --索引值為null,並且鍵存在的文檔
db.center.find({"z":null}) --鍵不存在的文檔也會返回.
Regex:
查詢數組:
db.cneter.find({fruit:{$all:["apple","banana"]}})
$all --通過多個元素來匹配數組,如果使用$all匹配一個元素,則和單獨查詢沒有區別.
以上查詢含有重複多行的數組,只返回一次;對只包含查詢值得數組,也不會返回.
查詢數組特定位置的值:db.cneter.find({"fruit.2":"peach"})
$size --查詢特定長度的數組
db.center.find("fruit":{"$size":3}})
$slice --返回某個鍵匹配的數組元素的一個子集
db.blog.findone(criteria,{"comments":{"$slice":10}}) --返回前10條評論
db.blog.findone(criteria,{"comments":{"$sliice":-10}}) --返回後10條評論
db.blog.findone(criteria,{"comments":{"$slice":[20,30]}})
$slice會返迴文檔中所有的鍵
返回匹配的數組元素:db.blog.find({"comments.name":"bob",{"comments.$":1}})
只會返回第一個文檔,如果bob有多條評論,只有第一條評論會被返回.
$elemMatch --同時使用查詢條件中的戀歌語句與一個數組元素進行比較,但不會匹配非數組元素
db.test.find({"x":{"$elemMatch":{"$gt":10,"$lt":20}}})
內嵌文檔的查詢:
db.people.find({"name.first":"joe","name.last":"schmoe"}) --與查詢順序無關.
db.people.find({"name":{"first":"joe","last":"schmoe"}}) --文檔必須精確匹配
正確指定一組條件,而不必指定每一鍵,需要使用$elemMatch:
db.blog.find({"comments":{"$elemMatch":{"author":"joe","score":{"$gt":5}}}})
$where:
db.foo.find({"$where":function(){
for(var current in this){
fro(var other in this){
if (current != other && this[current]==this[other]){
return true;
}
}
}
return false;
}})
伺服器端javascript很容易受到注入攻擊,可以在運行mongodn時指定--noscripting
遊標:for(i=0;i<100;i++){
db.cillection.insert({x:i})
}
var cursor = db.collection.find();
db.center.find().limit(3):限制返回查詢結果的數量
db.center.find().skip(3):略過查詢結果的前三個傳回值
db.center.find().sort({username:1,age:-1}):根據欄位名進行排序,1:升序,-1:降序
對混合類型的鍵排序,其順序排序是預先定義好的:
最小值<null<數字<字串<對象/文檔<數組<位元據<對象ID<布爾型<日期型<時間戳記<Regex<最大值
避免skip跳過大量的資料:
var page1=db.foo.find().sort({"date":-1}).limit(100)
var latest=null
//顯示第一頁
while(page1.hashNext()){
latest=page1.next();
display(latest);
}
//擷取下一頁
var page2=db.foo.find({"date":{"$gt":latest.date}});
page2.sort({"date":-1}).limit(100);
選取隨機文檔:
//效率不高的使用方法
var total=db.foo.count()
var random = Math.floor(Math.random()*total)
db.foo.find().skip(random).limit(1)
可在插入資料的時候增加一個額外的隨機鍵:
db.people.insert({"name":"joe","random":Math.random()})
var random =Math.random()
result= db.people.findOne({"random":{"$gt":random}})
進階查詢選項:
$maxscan:指定查詢中掃描文檔數量的上限
db.foo.find(criteria)._addSpecial("$maxscan":20)
$min:查詢的開始條件
$max:查詢的結束條件
$showDiskLoc:用於顯示該條結果在磁碟上的位置
db.foo.find()._addSpecial(‘$showDiskLoc‘,true)
查詢的時候,遊標右移,當問道那個返回資料庫的時候,體積增大,預留的空間不足,會挪至集合的末尾處,導致遊標到末尾。
解決:使用快照.db.foo.find().snapshot()
快照會使查詢變慢,只在必要時使用快照.
資料庫遊標在應用程式一段時間不使用的時候,會自動銷毀遊標,為了延長遊標的使用時間,使用immortal函數,使遊標不逾時.
資料庫命令:
db.listCommands():查看所有的資料庫命令
有些命令需要使用管理員權限:而且需要在admin庫上才能執行.
在其他庫執行管理員命令:
use temp
db.adminCommand({"shutdown":1})
---------------------------------------------------------------------------------------------------
設計應用
--------
索引
----
使用explain()查看在查詢過程所做的所有事情.
db.users.find({username:"kasumi"}).explain()
建立索引:db.users.ensureIndex({"username":1})
建立索引如果沒能在幾秒內返回,可在另外一個shell執行:db.currentOp()或者查看mongod的日誌查看索引建立的進度.
缺點:
對於添加的每一個索引,每次寫操作(插入、更新、刪除)都會消耗更多的時間,資料發生變動的時候,不僅需要更新文檔,還要更新集合上的所有索引.
查詢結果的預設排序是升序.
結果集的大小超過32MB,資料庫就會出錯,拒絕對如此多的資料進行排序.
索引實質上是樹,最小的值在最左的子葉上,最大的值在最右的子葉上.使用新資料較多--保留這棵樹最右側的資料,儘可能使索引右平衡.
低效率的操作符:
$where、$exists --不能使用索引
盡量使用$in而不是$or --兩次查詢將結果合并的效率不如單詞查詢的高,$or就是將兩次查詢的結果合并.
建立在文檔上的索引,只有完全符合的子文檔才會使用索引,對子文檔的查詢,需要建立子文檔的索引.
多鍵索引:這個鍵在某個文檔中是一個數組,被標記為多鍵索引,被標記為多鍵索引後,只能刪除索引再重建,才能恢複為非多鍵索引.
索引基數:集合中某個欄位擁有的不同值得數量.
一個欄位的基數越高,這個鍵上的索引越有用.
在基數較高的欄位上建立索引,將基數較高的鍵放在複合索引之前.(基數較低的鍵之前)
hint():強制使用指定的索引
db.c.find({"age":14,"username":/.*/}).hint({"username":1,"age":1})
--預設使用("age":1,"username":1) --先進行精確匹配再進行模糊比對
查詢最佳化工具:
如果有多個可用的索引,結果先返回的查詢計劃被緩衝,其他查詢會被中止.
explain()中allplans會顯示所有嘗試過的查詢計劃.
{"$natural":1} --強制使用全表掃描,返回結果是按照磁碟上的順序排列的.
索引類型:
---------
唯一索引:
db.users.ensureIndex({"username";1},{"unique":true}) --重複的值將不能插入
如果集合中已經存在重複值了,再建立唯一索引會導致失敗.
db.users.ensureIndex({"username";1},{"unique":true,"dropDups":true}) --遇到重複值得時候會刪除
稀疏索引:
db.ensureIndex({"email":1},{"unique":true,"sparse":true}) --欄位可以沒有值,但是當欄位有值的時候必須是唯一的.
索引管理:
--------
資料庫索引資訊儲存在system.indexes集合中,這是一個保留集合,不能在其中插入或者刪除文檔
只能通過ensureIndex或者dropIndexes對其進行操作.
db.[collectionName].getIndexes():查看給定集合上的所有索引資訊.
建立索引的時候,會阻塞所有對資料庫的讀請求和寫請求,一直到索引建立完成為止.
建立索引的時候使用background選項,建立索引時,如果有新的資料庫請求要處理,建立索引的過程會暫停一下.
特殊的索引和集合:
-----------------
固定集合:
---------
向已經佔滿的固定集合中插入資料,固定集合會將最老的文檔從集合中自動刪除.
db.createCollection("my_collection",{"capped":true,"size":10000})
將已有的常規集合轉換為固定集合:db.runCommand({"convertToCapped":"test","size":10000})
自然排序:
db.my_collection,find().sort({"$natural":-1})
沒有_id索引的集合:
調用createCollection建立集合的時候,指定autoIndexId為false.
沒有_id索引的集合,不能複製所在的mongod.
2.2版本之前,固定集合預設是沒有_id索引的.
TTL索引:
-------
為每一個文檔設定一個逾時時間,一個文檔達到預設的老化程度之後,就會被刪除.
db.foo.ensureIndex({"lastUpdated":1},{"expireAfterSecs":60*60*24})
全文本索引:
----------
db.adminCommand({"setParameter":1,"textSearrchEnabled":true}) --啟用全文本索引
權重:db.hn.ensureIndex({"title":"text","desc":"text","author":"text"},{"weights":{"title":3,"author":2}}) --預設值為1
索引一經建立就不能改變欄位的權重了.
GridFS隱藏檔: --用來儲存大型二進位檔案
1.使用GridFS能夠簡化棧.
2.GridFS會自動平衡已有的複製或為mongodb設定自動分區,所以對檔案儲存體做容錯移轉或者橫向擴充會更加容易.
3.用於儲存使用者上傳的檔案時,GridFS可以比較從容得解決其他一些檔案系統可能遇到的問題.
4.檔案儲存體的集中度會比較高.
缺點:
1.效能比較低.
2.如果要修複GridFS上的文檔,只能將已有的文檔刪除,然後再將整個文檔重新儲存.
from pyymongo import Connection
import gridfs
db = Connection().test
fs = gridfs.GridFS(db)
file_id = fs.put("hello ,kasumi",filename="foo.txt")
fs.list()
fs.get(file_id).read()
彙總:
-----
彙總架構:
篩選filtering、投射projecting、分組grouping、排序sorting、限制limiting、跳過skipping
db.articles.aggregate({"$project":{"author":1}},{"$group":{"_id":"$author","count":{"$sum":1}}},{"$sort":{"count":-1}},{"$limit":5})
數學運算式:
$add: +
$subtract: -
$multiply: *
$divide: /
$mod: 求餘
db.employees.aggregate({"$project":{"totalplay":{"$add":["$salary","$bonus"]}}})
字串運算式:
$substr:在第一個參數的字元中,從第二個參數開始,截取第三個參數的位元組數
$concat:將給定的字串串連起來
$toLower:
$toUpper:
邏輯運算式:
數組操作符:
$addToSet:如果參數不在數組中,則將它添加到數組中.
$push:無條件的添加參數到數組中.
db.runCommand({"distinct":"people","key":"age"}) --指定集合和鍵
應用程式設計:
-------------
範式可以提高資料的寫入速度,反範式能夠提高資料的讀取速度.
刪除舊資料:
固定集合:當集合被填滿的時候,將舊資料從固定集合中擠出.
TTL集合:更加精確的控制文檔刪除的時機.
定期刪除文檔:每月使用單獨的文檔,定期刪除.
不適合使用mongodb的情境:
1.mongodb不支援事務.
2.在多個不同維度上對不同類型的資料進行串連.
3.使用工具不支援mongodb.
複製:
---------------------------------------------------------------------------------------------
棄置站台集:
-----------
用戶端不能在備份節點執行寫操作.
預設情況下,用戶端不能從備份節點中讀取資料.
複本集內的每個成員都必須能夠串連到其他所有成員.
複本集的組成:
--------------
同步:
複製功能是使用動作記錄oplog實現的,動作記錄包含了主節點的每一次操作.oplog是主節點的local資料庫中的一個固定的集合.
備份節點從當前使用的同步源中擷取需要執行的操作,然後再自己的資料集上執行這些操作.最後將這些操作寫入自己的oplog.
從應用程式串連複本集:
---------------------
主節點掛掉後,應用程式不能執行讀操作,如果希望主節點掛掉後,應用程式可以執行讀操作,可以從備份節點讀取資料.
從備份節點讀取資料的時候,並不在意讀到的資料是不是最新的.
低延遲的讀和寫:必須使用分區,複本集值允許在主節點上進行寫操作.
管理:
------
將成員的投票數量設定為0:
rs.add({"_id":1,"host":"server-1:27017","vote":0})
當複本集中數量較多時,可以設定某些成員沒有選舉許可權。
rs.reconfig(config,{"force":true}) --強制重新設定複本集
阻止選舉:
如果需要對主節點做維護,但是不希望這段時間內將其他成員選舉為主節點,那麼可以在每個備份節點上執行freeze命令,強制他們處於備份節點的狀態.
rs.freeze(10000)
釋放:rs.freeze(0)
監控複製:
---------
rs.status()
server1.adminCommand({replSetGetStatus:1})[‘syncingTo‘] -查看伺服器的同步源
增加oplog的大小:
1.如果當前節點是主節點,讓它退位,以便讓其他成員的資料能夠儘快更新到與它一致.
2.關閉當前伺服器.
3.將當前伺服器以單機模式啟動.
4.臨時將oplog的最後一條insert操作儲存到其他集合中.
5.刪除當前的oplog:db.oplog.rs.drop()
6.建立一個新的oplog:db.createCollection("oplog.rs",{"capped":true,"size":10000})
7.將最後一條操作記錄寫回oplog
確保資料插入成功,如果沒有插入成功,將伺服器添加到複本集後,會刪除所有資料。
8.將伺服器作為複本集重新啟動.
主從設定:
mongod --master
mongod --slave --source masterip:port
主從模式切換到複本集模式:
1.停止系統所有的寫操作.
2.關閉所有的mongod服務.
3.使用--replSet選項重啟主節點.
4.初始化這個只有一個成員的複本集.
5.使用--replSet和--fastsync選項啟動從節點.
6.使用rs.add()將之前的從節點加入複本集.
7.對每個從節點重複5-6步.
8.當所有從節點變為備份節點之後,就可以開啟系統寫的功能了.
9.從設定檔、命令列和記憶體中刪除fastsync選項.
分區:
-------------------------------------------------
分區:
------
sh.status()可以看到叢集的狀態:分區摘要資訊、資料庫摘要資訊、集合摘要資訊.
主分區與複本集中的主節點不同.主分區指的是組成分區的整個複本集,而複本集中的主節點指的是能夠處理寫請求的單台伺服器.
要對一個集合分區,首先要對這個集合的資料庫啟用分區:sh.enableSharding("center")
在啟用分區之前,現在希望作為片鍵的鍵上建立索引:db.users.enableIndex({"username":1})
根據username對集合進行分區:sh.shardCollection("center.users",{"username":1})
如果有多個現存的複本集沒有作為分區,只要他們沒有同名的資料庫,就可以將它們作為全新的分區全部添加到叢集中.
db.locks.findOne({"_id":"balancer"}) --查看mongos的均衡器.
mongos:
use config
db.shards.find() --查看叢集內所有的分區資訊.
db.databases.find() --追蹤記錄所有資料庫的資訊.
db.collection.find() --追蹤記錄所有分區集合的資訊.
chunks --記錄集合中所有塊的資訊
changelog --追蹤記錄叢集的操作
db.tags.find() --為系統配置分區標籤時發生的.
settings --當前均衡器設定和塊大小的文檔資訊.
查看串連統計:db.adminCommand({"connPoolStats":1})
host1這樣的主機名稱是來自設定管理員的串連,name/host1這樣的主機是來自分區的串連.
在mongos和mongod上運行命令才會有效.
添加伺服器:
只要保證在mongos的--configdb選項中指定了一組正確的佈建服務,mongos可立即與用戶端建立串連.
修改分區的伺服器:
只有在使用單機伺服器作為分區,而不是使用複本集作為分區時,才需手動修改config.shards.
將單機伺服器分區修改為複本集分區:
1.停止向系統發送請求
2.關閉單機伺服器server1和所有的mongos進程
3.以複本集模式重啟伺服器server1
4.串連到server1,將其作為一個但成員複本集進行初始化
5.串連到設定管理員,替換該分區的入口,在config.shards中將分區的名稱替換.
刪除分區:
db.adminCommand({"removeShard":"server1"})
保證均衡器開啟的情況下,刪除分區的時候,會將資料移轉至其他分區.
查看執行的狀態,可以再次執行以上命令,查看當前的狀態.
資料均衡:
sh.setBalancerState(false) --執行所有的資料庫管理操作執勤啊,都應該先關閉均衡器.
db.locks.find({"_id":"balancer"})["state"] --檢查均衡器是否關閉
重新整理配置:
db.adminCommand({"flushRouterConfig":1}) --手動重新整理所有緩衝.
應用管理:
----------------------------------------------------------------------------------------------
查看進行中的操作:
db.currentOp()
使用系統分析器來尋找耗時過長的操作,但是mongod的整體效能也會有所下降,因此只定期開啟分析器來擷取資訊.
db.setProfilingLevel(2)
將分析層級設為0可關閉分析器:db.setProfilingLevel(0)
mongotop --查看那個集合最繁忙
mongostat --提供有關伺服器的資訊,預設每秒輸出一次包含目前狀態的列表.
資料管理:
---------
身份認證:
分區時,資料庫admin會被儲存在設定管理員上,所以分區中的mongod甚至並不知道它的存在,
因此,在它們看來,它們雖然開啟了身份認證但卻不存在管理使用者。於是,分區會允許一個本地的local用戶端無需身份認證便可讀寫資料.
將網路設定為止允許用戶端訪問mongos進程即可.不過,如果擔心用戶端在分區的本地上運行,不通過mongos進程而直接連接到分區的話,可在分區中添加管理使用者.
移動集合:
無法在資料庫間移動集合,但可更改集合名:db.sourceColl.renameCollection("newname")
將一個集合移動到另一個mongod中:db.runCommand({"cloneCollection":"collName","from":"histname:port"})
持久性:
--------
mongod內建恢複工具:mongod --dbpath /data/gst/mongodb2.6.12/data --repair [--repairpath /data]:指定恢複的目錄
mongodump --repair
mongod.lock檔案:如果啟用了日記系統,則這一檔案不會出現
mongod正常退出的時候,會清除這一檔案,如果沒有清除檔案,則說明mongod非正常退出.
mongod.lock檔案會阻止mongod的啟動,如果mongod.lock阻止了mongod的啟動,不能單純的刪除mongod.lock檔案,需要對資料進行修複.
伺服器管理:
----------------------------------------------------------------------------------------------
啟動和停止mongodb:
-------------------
--dbpath
--port
--fork
--logpath
--directoryperdb:將每個資料庫存放在單獨的目錄中
--config
啟動資料庫的時候,mongodb會將一個文檔寫入local.startup_log >db.startup_log.find()
關閉:
admin庫:db.shutdownServer()
db.adminCommand({"shutdown":1,"force":true}) --強制關閉
監控mongodb:
------------
備份:
-----
複製資料檔案:
db.fsyncLock() --鎖定資料庫,禁止任何寫入,並進行同步.所有的寫入操作排入佇列等待.
db.fsyncUnlock()
mongodump / mongorestore:--drop在恢複一個集合前先刪除.
對複本集進行備份:
對備份節點進行備份,減輕主節點的負擔.
使用mongodump在備份的時候,需要使用--oplog,得到基於某個是簡單的快照,否則備份的狀態不會和任何其他叢集成員的狀態相吻合.
恢複的時候需要運行--oplogReplay.
對分區叢集進行備份:
整個叢集:
關閉均衡器,通過mongos運行mongodump,恢複備份需要運行mongorestore並串連到一個mongos.
mongooplog進行增量備份:
1.記錄下A的oplog中最近一次的操作時間
op=db.oplog.rs.find().sort({$natural:-1}).limit(1).next();
start =op[‘ts‘][‘t‘]/1000
2.對資料進行備份,恢複備份至B上的資料庫目錄
3.定期添加A上的操作至B,從而完成資料的複製.
mongooplog --from A --seconds 1234567
seconds後的參數,應該為第一步中計算得到的start變數和目前時間的差值,再額外加上幾秒.
部署mongodb:
------------
MongoDB權威指南--筆記