我正在尝试在两个环境之间复制mongo索引。检查了API,发现没有直接的方法。所以我开始编写一个连接到一个db的脚本,遍历集合,抓取索引,改变它们(因为getIndexes()
和ensureIndex()
具有不同的格式),连接到另一个db,擦除索引并复制新的。
这一切都略微超过了顶部所以我认为我必须遗漏一些东西。
有任何建议/良好做法吗?除了有索引创建策略。
干杯!
答案 0 :(得分:3)
请在要复制索引的数据库上运行它。
db.getCollectionNames().forEach(function(collection) {
indexes = db[collection].getIndexes();
indexes.forEach(function (c) {
opt = ''
ixkey = JSON.stringify(c.key, null, 1).replace(/(\r\n|\n|\r)/gm,"")
ns = c.ns.substr(c.ns.indexOf(".") + 1, c.ns.length)
for (var key in c) {
if (key != 'key' && key != 'ns' && key != 'v') {
if (opt != '') { opt+= ','}
if (c.hasOwnProperty(key)) {
if (typeof(c[key]) == "string") {
opt += (key + ': "' + c[key] + '"')
} else {
opt+= (key + ": " + c[key])
}
}
}
}
if (opt != '') { opt = '{' + opt + '}'}
print ('db.' + ns + '.ensureIndex(' + ixkey + ','+ opt + ')')
})});
答案 1 :(得分:3)
我更新了Adamo Tonete的脚本
db.getCollectionNames().forEach(function(col) {
var indexes = db[col].getIndexes();
indexes.forEach(function (c) {
var fields = '', result = '', options = {};
for (var i in c) {
if (i == 'key') {
fields = c[i];
} else if (i == 'name' && c[i] == '_id_') {
return;
} else if (i != 'name' && i != 'v' && i != 'ns') {
options[i] = c[i];
}
}
var fields = JSON.stringify(fields);
var options = JSON.stringify(options);
if (options == '{}') {
result = "db." + col + ".createIndex(" + fields + "); ";
} else {
result = "db." + col + ".createIndex(" + fields + ", " + options + "); ";
}
result = result
.replace(/{"floatApprox":-1,"top":-1,"bottom":-1}/ig, '-1')
.replace(/{"floatApprox":(-?\d+)}/ig, '$1')
.replace(/\{"\$numberLong":"(-?\d+)"\}/ig, '$1');
print(result);
});
});
答案 2 :(得分:1)
尝试使用此脚本:
var i, c,
co_name, co_new,
co_old, co_old_i,
_db = db.getSiblingDB('logs'),
_colls = ['activity.games', 'activity.session', 'activity.social', 'activity.store'];
for (i in _colls){
co_name = _colls[i];
co_old = _db[co_name];
co_old_i = co_old.getIndexes();
if(co_old.count() > 0){
co_old.renameCollection(co_name + '.old');
_db.createCollection(co_name);
co_new = _db[co_name];
for(c in co_old_i){
co_new.ensureIndex(co_old_i[c].key);
}
}
}
https://gist.github.com/alejandrobernardis/8261327
此致 甲
答案 3 :(得分:1)
这是一个使用选项重新创建它们的版本,以及使用新的createIndex命令而不是ensureIndex(因为mongoDB 3.0)。这样,将所有索引从一个DB复制(重新创建)到另一个DB非常容易。
function createIndex2( coll, keys, options ) {
var ret = db[coll].createIndex(keys, options)
if (ret.createdCollectionAutomatically) print( "Collection " + coll + " was created")
if (ret.errmsg || (ret.note != "all indexes already exist" && ret.ok != 1)) {
ret.coll = coll
ret.keys = keys
ret.options = options
print(tojson(ret))
} else {
//print( "Everything normal", JSON.stringify(ret))
}
}
db.getCollectionInfos().forEach(function(coll) {
//print( JSON.stringify( coll ))
if (coll.type === "collection" ) {
db[coll.name].getIndexes().forEach(function(index) {
if ("_id_" !== index.name) {
//print( JSON.stringify( index ))
var indexKey = index.key // save the key, and transform index into the "options"
delete index.key
delete index.ns // namespace - not necessary
delete index.v // not necessary
index.background = true // optional: force background to be true
//native version: print("db." + coll.name + ".createIndex(" + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
// this gives much more debug info
print("createIndex2(\"" + coll.name + "\", " + JSON.stringify(indexKey) + ", " + JSON.stringify(index) + ")");
}
});
}
});
结果看起来如果使用“本机”版本,否则,它将只显示错误:
db.dishes.createIndex({ “子菜单”:1}, { “名”: “submenu_1”, “NS”: “dishly.dishes”, “背景”:真}) db.dishes.createIndex({ “LOC”: “2dsphere”}, { “名称”: “loc_2dsphere”, “NS”: “dishly.dishes”, “2dsphereIndexVersion”:3, “背景”:真}) db.dishes.createIndex({ “RS”: - 1}, { “名”: “RS_-1”, “NS”: “dishly.dishes”, “partialFilterExpression”:{ “RS”:{ “$ GTE”:3}}, “背景”:真}) db.dishes.createIndex({ “LOC”: “2D”, “类型”:1, “状态”:1, “FSID”:1, “RS”: - 1}, { “名称”: “loc_2d_type_1_status_1_rs_-1”, “NS”: “dishly.dishes”, “背景”:真 “partialFilterExpression”:{ “RS”:{ “$ GTE”:2}}}) db.dishes.createIndex({ “_ FTS”: “文本”, “_ ftsx”:1, “loc.0”:1, “loc.1”:1, “RS”: - 1}, { “名”: “d2_menu_submenu_text__loc__rs”, “NS”: “dishly.dishes”, “背景”:真正的 “砝码”:{ “D2”:1, “菜单”:1, “子菜单”:1}” DEFAULT_LANGUAGE “:” 英语”, “language_override”: “语言”, “textIndexVersion”:3})