|
/* |
|
How to (required index.js exported from exporter.js) |
|
* mongo is mongoshell command |
|
|
|
mongo dbname --quiet --eval "let mode='DRYRUN';" mongodbIndexImporter.js |
|
|
|
*/ |
|
|
|
// available modes |
|
let LIVE = 'LIVE'; |
|
let DRYRUN = 'DRYRUN'; // actually all other words except 'LIVE' are DRYRUN mode. |
|
|
|
load('index.js'); |
|
if(typeof mode == 'undefined') { |
|
print(red('mode variable required!')+' '+cyan('--eval "let mode=\'DRYRUN\';" or "let mode=\'LIVE\';')); |
|
} |
|
else { |
|
print('*** Index importer: started with ' + yellow(mode) + ' mode ***'); |
|
|
|
let collections = indexes['collections']; |
|
let collectionNames = db.getCollectionNames(); |
|
|
|
for (let i in collections) { |
|
let collection = collections[i]; |
|
let indexItems = collection["indexes"]; |
|
let collectionName = collection['name']; |
|
print('='.repeat(55)); |
|
if (collectionNames.indexOf(collectionName) >=0) { |
|
print('collection '+ green(collectionName) + ' already '+green('exists')); |
|
} else { |
|
print('will '+yellow('create')+' collection '+ green(collectionName)); |
|
if (mode == LIVE) { |
|
// do create collection |
|
db.createCollection(collectionName) |
|
} |
|
} |
|
|
|
let dbCollection = db.getCollection(collectionName); |
|
let existingIndexes = dbCollection.getIndexes(); |
|
|
|
for(let itemIdx in indexItems) { |
|
let indexItem = indexItems[itemIdx]; |
|
let indexName = indexItem['name']; |
|
let indexKey = indexItem['key']; |
|
let checked = false; |
|
for(let eIdx in existingIndexes) { |
|
let existingIndex = existingIndexes[eIdx]; |
|
if (existingIndex['name'] == indexName) { |
|
if(!isSameKey(existingIndex, indexItem)) { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+red('dropped')); |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+yellow('re-created')); |
|
if(mode == LIVE) { |
|
dbCollection.dropIndex(indexName); |
|
createIndex(dbCollection, indexName, indexItem); |
|
} |
|
} |
|
else { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' is same, skip.'); |
|
} |
|
checked = true; |
|
break |
|
} |
|
} |
|
|
|
if (!checked) { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+yellow('created')); |
|
if(mode == LIVE) { |
|
createIndex(dbCollection, indexName, indexItem); |
|
} |
|
} |
|
} |
|
|
|
for(let eIdx in existingIndexes) { |
|
let checked = false; |
|
let existingIndex = existingIndexes[eIdx]; |
|
for(let itemIdx in indexItems) { |
|
let indexItem = indexItems[itemIdx]; |
|
let indexName = indexItem['name']; |
|
if (existingIndex['name'] == indexName) { |
|
checked = true |
|
break |
|
} |
|
} |
|
|
|
if (!checked) { |
|
print('collection '+green(collectionName)+' index '+green(existingIndex["name"])+' will be '+red('dropped')); |
|
if (mode == LIVE) { |
|
dbCollection.dropIndex(existingIndex["name"]); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (mode == LIVE) { |
|
print('Completed! '+magenta('LIVE MODE. All Operatoins are applied on database!')); |
|
} |
|
else { |
|
print('Completed! '+cyan('TEST MODE. Nothing is applied.')); |
|
} |
|
} |
|
|
|
function createIndex(db, name, indexItem) { |
|
let options = {'name': name}; |
|
let key = indexItem['key']; |
|
if('expireAfterSeconds' in indexItem) { |
|
options['expireAfterSeconds'] = indexItem['expireAfterSeconds']; |
|
} |
|
|
|
if('background' in indexItem) { |
|
options['background'] = indexItem['background']; |
|
} |
|
|
|
if('unique' in indexItem) { |
|
options['unique'] = indexItem['unique']; |
|
} |
|
|
|
if('collation' in indexItem) { |
|
options['collation'] = indexItem['collation']; |
|
} |
|
|
|
db.createIndex(key, options); |
|
} |
|
|
|
function isSameKey(existingIndex, newIndex) { |
|
let key = existingIndex['key']; |
|
let newKey = newIndex['key']; |
|
|
|
// -2: v, ns |
|
let excepted = 0; |
|
for (let keyName in existingIndex) { |
|
if (keyName === "v") { |
|
excepted++ |
|
continue |
|
} |
|
|
|
if (keyName === "ns") { |
|
excepted++ |
|
} |
|
} |
|
|
|
if (Object.keys(existingIndex).length -excepted != Object.keys(newIndex).length) { |
|
return false; |
|
} |
|
|
|
if (Object.keys(key).length != Object.keys(newKey).length) { |
|
return false; |
|
} |
|
|
|
for(let i in key) { |
|
let val = key[i]; |
|
if(i in newKey) { |
|
if(newKey[i] != val) { |
|
return false; |
|
} |
|
} |
|
else { |
|
return false; |
|
} |
|
} |
|
let except = ['v', 'ns', 'key']; |
|
for (let element in existingIndex) { |
|
if (except.indexOf(element) >= 0) { |
|
continue; |
|
} |
|
|
|
if (existingIndex[element] != newIndex[element]) { |
|
let a = existingIndex[element]; |
|
let b = newIndex[element]; |
|
if (isObject(a) && isObject(b)) { |
|
print(element) |
|
for (let el in b) { |
|
if (a[el] != b[el]) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
|
|
} |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function isObject(val) { |
|
if (val === null) { return false;} |
|
return ( (typeof val === 'function') || (typeof val === 'object') ); |
|
} |
|
|
|
// colors |
|
function red (text) { return colorize(text, 'red') } |
|
function green (text) { return colorize(text, 'green') } |
|
function yellow (text) { return colorize(text, 'yellow') } |
|
function blue (text) { return colorize(text, 'blue') } |
|
function magenta (text) { return colorize(text, 'magenta') } |
|
function cyan (text) { return colorize(text, 'cyan') } |
|
function gray (text) { return colorize(text, 'gray') } |
|
|
|
function colorize(text, color, style) { |
|
// color: 'red', 'green', 'blue'... (see below) |
|
// styles: 'normal' or undefined, 'bright', 'highlight' |
|
|
|
if (!style) { |
|
style = 'normal'; |
|
} |
|
|
|
let _ansi = { |
|
csi: String.fromCharCode(0x1B) + '[', |
|
reset: '0', |
|
text_prop: 'm', |
|
|
|
styles: { |
|
normal: '3', |
|
bright: '9', |
|
highlight: '4' |
|
}, |
|
|
|
colors: { |
|
black: '0', |
|
red: '1', |
|
green: '2', |
|
yellow: '3', |
|
blue: '4', |
|
magenta: '5', |
|
cyan: '6', |
|
gray: '7' |
|
} |
|
}; |
|
|
|
let beginColor = _ansi.csi + _ansi.styles[style] + _ansi.colors[color] + _ansi.text_prop; |
|
let endColor = _ansi.csi + _ansi.reset + _ansi.text_prop; |
|
|
|
return beginColor + text + endColor; |
|
} |
@tungtnv Hi, What version do you use? Can you give me error message with version?
Currently, I'm using this on mongodb 4.4.
But If this script is not working on new version, I'll consider updating or creating another file on my gist.