最新遇到一个需求,要求备份gridFs中的部分数据。但是gridFs会把文件分成files和chunks两个集合来存储,我们知道files和chunks是通过id关联的,一个files会对应多个chunks中数据,所以普通的导出好像行不通
由于接触mongo不久,找不到其他导出的办法,我是通过js脚本实现从gridFs中过滤部分数据并且导出的
脚本内容如下
/*******start-setting*********/
const collection="tiles";//需要导出了mongodb中gridFs存储桶的名称
let ids=["thd5CG6wV","txxCapQvE"];//导出数据文件名的filename公有特性--支持模糊查询
//源数据库配置
const Origin_dataUrl="xxxxxx:27017";//数据源源地址ip+port
const Origin_dataBase="xxxxxx";//源数据库名称
const Origin_User="xxxxxx";//源数据库认证用户名
const Origin_Password="xxxxxx";//源数据库认证密码
//目标数据库配置
const Target_dataUrl="xxxxxx:27017";//数据源目标地址ip+port
const Target_dataBase="xxxxxx";//目标源数据库名称
const Target_User="xxxxxx";//目标源数据库认证用户名
const Target_Password="xxxxxx";//目标源数据库认证密码
/********end-setting**********/
var conn = new Mongo(Origin_dataUrl);
var db = conn.getDB(Origin_dataBase);//源数据库
db.auth(Origin_User,Origin_Password)
const sharding=1000;//分片数量
var targetConn = new Mongo(Target_dataUrl);
var targetDb=targetConn.getDB(Target_dataBase);//目标数据库
targetDb.auth(Target_User,Target_Password);
let filter=[];//拼接条件的标识
for (var i = 0; i < ids.length; i++) {
filter.push({"filename":{ "$regex":"^"+ids[i]}})
}
var count=db.getCollection(collection+".files").find({ "$or": filter}).count();//源数据库总记录数
let _id="";//id下标
let _id_xb="";
let start=0;//游标
let old="";
while(count>start){
if(_id==""){
_id_xb={}
}else{
_id_xb={
"_id": {
"$gt": _id
}
}
}
var c = db.getCollection(collection+".files").find({ "$or": filter,"$and": [_id_xb]}).sort({"_id":1}).limit(sharding);
while(c.hasNext()) {
let json=c.next();
targetDb.getCollection(collection+".files").insert([json]);
_id=json._id;
start++;
let progress=Math.trunc((start/count)*100);
//print("剩余完成:"+progress, end="\t")
if(old!=progress){
print("已完成进度:"+progress+"%")
}
old=progress;
var chunks_res=db.getCollection(collection+".chunks").find({"files_id":_id})
while(chunks_res.hasNext()){
let chunks_json=chunks_res.next();
targetDb.getCollection(collection+".chunks").insert([chunks_json]);
}
}
}
最后进入mongo安装bin目录执行 ----->mongo XXX.js
*mongo菜鸟一个,只是记录*