【背景】
最近接到这样的需求,需要生产环境所有MongoDB的表结构导入一份到测试环境包括集合的分片信息以及对应索引.我们知道MongoDB是动态模式,每一行对应列可能都不同以及索引信息也没有类似数据字典去记录,需要通过循环每个db以及每个集合去getIndexes()(老版本有类似数据字典可以查询),我们环境中分片以及索引创建都是dba去创建,没有在代码中创建(如果在代码中生成,直接搭建好MongoDB环境启动应用即可自动生成),本次主要针对非代码自动创建的情况如何快递导出MongoDB结构.
【分析过程】
手动创建分片集合以及索引步骤:
1、对db开启分区--没有则跳过
sh.enableSharding('db','primaryshard');
2、对集合开启分片--range、hash以及组合--没有则自动跳过
sh.shardCollection('db.collection',{分片字段:1})
3、创建需要的索引--没有自动跳过
db.getSiblingDB('db').collectionname.createIndexes([{a:1},{b:1}])
如果手动创建少量对象还可以,如果需要创建几百个对象上千个,估计这个手工累的够呛.如果此时能够批量生成对应语句,然后在测试环境直接执行,那就可以解放我们的小手了.
【以下是简陋脚本实现以上功能--将生成的脚本直接复制测试环境执行即可】
【生成分片db语句】
db.getSiblingDB('config').databases.find({"partitioned" : true}).forEach(function(db){
print("sh.enableSharding(" + '"'+db._id + '"'+","+'"'+db.primary+'")');
})
--输出以下结果
sh.enableSharding("xiaoxu1","shard1")
sh.enableSharding("xiaoxu2","shard2")
sh.enableSharding("xiaoxu3","shard3")
sh.enableSharding("xiaoxu4","shard4")
sh.enableSharding("xiaoxu5","shard5")
【不包括primarShard属性】
db.getSiblingDB('config').databases.find({"partitioned" : true}).forEach(function(db){
print("sh.enableSharding(" + '"'+db._id + '")');
})
--输出以下结果
sh.enableSharding("xiaoxu1")
sh.enableSharding("xiaoxu2")
sh.enableSharding("xiaoxu3")
sh.enableSharding("xiaoxu4")
sh.enableSharding("xiaoxu5")
【生成表分片语句】
db.getSiblingDB('config').collections.find({"dropped":false}).
forEach(function(collection){
print("sh.shardCollection('" + collection._id + "'"+",");
printjson(collection.key);
print(","+collection.unique+");");
})
--输出以下格式
sh.shardCollection('xiaoxu3.expInform',
{ "_id" : "hashed" }
,false);
sh.shardCollection('xiaoxu4.monitor',
{ "org" : 1, "ct" : 1 }
,false);
sh.shardCollection('xiaoxu5.opDeleteIn',
{ "no" : "hashed" }
,false);
【列出所有DB下的索引信息,也可以查看特定DB,只需要在find后面指定查询条件即可】
db.getSiblingDB("config").databases.find({}).forEach(function(d){
mdb=db.getSiblingDB(d._id);
mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){
currentCollection = mdb.getCollection(c.name);
indexes=currentCollection.getIndexes()
print("db.getSibilingDB("+"'"+mdb+"')."+"runCommand({ ");
print("createIndexes: " + '"' + c.name+ '"' + ",");
print("indexes: ");
printjson(indexes);
print("});");
})
});
--输出以下格式
db.getSibilingDB('xiaoxu3').runCommand({
createIndexes: "expInform",
indexes:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"_id" : "hashed"
},
"name" : "_id_hashed"
}
]
});
db.getSibilingDB('xiaoxu').runCommand({
createIndexes: "xiaoxu",
indexes:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
});
【总结】
通过以上脚本,我们可以快速把生产环境结构复制一份到测试环境,当需要有大量集合需要复制时,通过脚本可以节约时间同时降低错误率.