如何快速批量导出MongoDB结构

2022-09-22 11:45:18 浏览数 (1)

背景

最近接到这样的需求,需要生产环境所有MongoDB的表结构导入一份到测试环境包括集合的分片信息以及对应索引.我们知道MongoDB是动态模式,每一行对应列可能都不同以及索引信息也没有类似数据字典去记录,需要通过循环每个db以及每个集合去getIndexes()(老版本有类似数据字典可以查询),我们环境中分片以及索引创建都是dba去创建,没有在代码中创建(如果在代码中生成,直接搭建好MongoDB环境启动应用即可自动生成),本次主要针对非代码自动创建的情况如何快递导出MongoDB结构.

分析过程

代码语言:javascript复制
  手动创建分片集合以及索引步骤:

  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语句

代码语言:javascript复制
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属性】

代码语言:javascript复制
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")

生成表分片语句

代码语言:javascript复制
db.getSiblingDB('config').collections.find({"dropped":false}).
forEach(function(collection){
print("sh.shardCollection('"   collection._id   "'" ",");
printjson(collection.key);
print("," collection.unique ");");
})

--输出以下格式

代码语言:javascript复制
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后面指定查询条件即可

代码语言:javascript复制
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("});");
})
});

--输出以下格式

代码语言:javascript复制
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_" } ]
});

【总结】

通过以上脚本,我们可以快速把生产环境结构复制一份到测试环境,当需要有大量集合需要复制时,通过脚本可以节约时间同时降低错误率.

0 人点赞