mongodb如何將查詢結果保存到新的集合中
背景:
遇到一個現實問題,生產環境mongodb中有一個集合達到1.7T,磁盤空間緊張。經過核實確認,需要刪除歷史數據,僅需要保存最近半年的數據即可。
初步估算,大約可節約1.2T的空間(由於客觀原因,期間業務開發人員也換了好幾撥,長期積累下來,就這么一直到現狀)。
那么,問題來了,如何才能實現了?
首選想到的就是,將歷史數據分批刪掉,然后收縮表空間即可。誠然,這樣做理論上是可以的,但是實現起來比較麻煩可行性較低。
這里,就以標題為核心,來說明如何操作。
1、假定磁盤空間還能存儲下所需要的數據量大小為前提;
2、將根據條件查詢出來的結果保存到新的集合中(期間不要有數據變化);
3、將原集合重名為其他;
4、將新集合重名為元集合名;
5、此時,如果有條件,可備份需要drop掉的集合,確實不需要的話,可drop掉(實踐中,drop掉大集合,不會像drop mysql的大表那樣產生磁盤IO問題);
直接上操作步驟
# 准備測試數據
use testdb
show dbs
var arr=[]
for (var i = 1; i <= 200000 ; i++){
arr.push({"seqs":i});
}
db.t1.insert(arr)
# 將查詢結果保存到新的集合中
var results = db.getCollection("t1").find({
"seqs": {
$gte: 10000
}
})
while(results.hasNext()) db.t3.insert(results.next())
步驟1、插入測試數據
use testdb
show dbs
var arr=[]
for (var i = 1; i <= 200000 ; i++){
arr.push({"seqs":i});
}
db.t1.insert(arr)
drgcore:PRIMARY> use testdb switched to db testdb drgcore:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.018GB testdb 0.000GB drgcore:PRIMARY> var arr=[] drgcore:PRIMARY> for (var i = 1; i <= 200000 ; i++){ ... arr.push({"seqs":i}); ... } db.t1.insert(arr)200000 drgcore:PRIMARY> db.t1.insert(arr) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 200000, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) drgcore:PRIMARY>
步驟2、確認數據
drgcore:PRIMARY> show tables system.profile t1 drgcore:PRIMARY> db.t1.find({"seqs":{$gte:10000}}) { "_id" : ObjectId("620470814b2140af349e0003"), "seqs" : 10000 } { "_id" : ObjectId("620470814b2140af349e0004"), "seqs" : 10001 } { "_id" : ObjectId("620470814b2140af349e0005"), "seqs" : 10002 } { "_id" : ObjectId("620470814b2140af349e0006"), "seqs" : 10003 } { "_id" : ObjectId("620470814b2140af349e0007"), "seqs" : 10004 } { "_id" : ObjectId("620470814b2140af349e0008"), "seqs" : 10005 } { "_id" : ObjectId("620470814b2140af349e0009"), "seqs" : 10006 } { "_id" : ObjectId("620470814b2140af349e000a"), "seqs" : 10007 } { "_id" : ObjectId("620470814b2140af349e000b"), "seqs" : 10008 } { "_id" : ObjectId("620470814b2140af349e000c"), "seqs" : 10009 } { "_id" : ObjectId("620470814b2140af349e000d"), "seqs" : 10010 } { "_id" : ObjectId("620470814b2140af349e000e"), "seqs" : 10011 } { "_id" : ObjectId("620470814b2140af349e000f"), "seqs" : 10012 } { "_id" : ObjectId("620470814b2140af349e0010"), "seqs" : 10013 } { "_id" : ObjectId("620470814b2140af349e0011"), "seqs" : 10014 } { "_id" : ObjectId("620470814b2140af349e0012"), "seqs" : 10015 } { "_id" : ObjectId("620470814b2140af349e0013"), "seqs" : 10016 } { "_id" : ObjectId("620470814b2140af349e0014"), "seqs" : 10017 } { "_id" : ObjectId("620470814b2140af349e0015"), "seqs" : 10018 } { "_id" : ObjectId("620470814b2140af349e0016"), "seqs" : 10019 } Type "it" for more drgcore:PRIMARY> db.t1.count({"seqs":{$gte:10000}}) 190001 drgcore:PRIMARY>
步驟3、將查詢的結果保存到t3中
var results = db.getCollection("t1").find({ "seqs": { $gte: 10000 } }) while(results.hasNext()) db.t3.insert(results.next())
drgcore:PRIMARY> db.t1.count({"seqs":{$gte:10000}}) 190001 drgcore:PRIMARY> drgcore:PRIMARY> drgcore:PRIMARY> var results = db.getCollection("t1").find({ ... "seqs": { ... $gte: 10000 ... } ... }) drgcore:PRIMARY> while(results.hasNext()) db.t3.insert(results.next()) WriteResult({ "nInserted" : 1 }) drgcore:PRIMARY>
drgcore:PRIMARY> db.t3.count({"seqs":{$gte:10000}})
190001
經過驗證,已經將所需要的數據保存到了新的集合t3中,此時,即可drop掉原有集合t1。
drgcore:PRIMARY> db.t1.renameCollection("t1_bak") { "ok" : 1 } drgcore:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.025GB testdb 0.010GB drgcore:PRIMARY> db.t3.renameCollection("t1") { "ok" : 1 } drgcore:PRIMARY> db.t1_bak.drop() true drgcore:PRIMARY> show dbs admin 0.000GB config 0.000GB local 0.025GB testdb 0.003GB drgcore:PRIMARY> show tables system.profile t1 drgcore:PRIMARY>