indexbuilder.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2015 The MemDB Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License. See the AUTHORS file
  14. // for names of contributors.
  15. 'use strict';
  16. /**
  17. * WARNING: Shutdown all cluster before running these scripts
  18. */
  19. var P = require('bluebird');
  20. var backends = require('./backends');
  21. var BackendLocker = require('./backendlocker');
  22. var Document = require('./document'); //jshint ignore:line
  23. var Collection = require('./collection');
  24. var utils = require('./utils');
  25. var logger = require('memdb-logger').getLogger('memdb', __filename);
  26. var ensureShutDown = function(lockingConf){
  27. lockingConf.shardId = '$';
  28. lockingConf.heartbeatInterval = 0;
  29. var backendLocker = new BackendLocker(lockingConf);
  30. return P.try(function(){
  31. return backendLocker.start();
  32. })
  33. .then(function(){
  34. return backendLocker.getActiveShards();
  35. })
  36. .then(function(shardIds){
  37. if(shardIds.length > 0){
  38. throw new Error('You should shutdown all shards first');
  39. }
  40. })
  41. .finally(function(){
  42. return backendLocker.stop();
  43. });
  44. };
  45. // dropIndex('field1 field2')
  46. exports.drop = function(conf, collName, keys){
  47. if(!Array.isArray(keys)){
  48. keys = keys.split(' ');
  49. }
  50. var indexKey = JSON.stringify(keys.sort());
  51. conf.backend.shardId = '$';
  52. var backend = backends.create(conf.backend);
  53. var indexCollName = Collection.prototype._indexCollectionName.call({name : collName}, indexKey);
  54. return ensureShutDown(conf.locking)
  55. .then(function(){
  56. return backend.start();
  57. })
  58. .then(function(){
  59. return backend.drop(indexCollName);
  60. })
  61. .finally(function(){
  62. logger.warn('Droped index %s %s', collName, indexKey);
  63. return backend.stop();
  64. });
  65. };
  66. // rebuildIndex('field1 field2', {unique : true})
  67. exports.rebuild = function(conf, collName, keys, opts){
  68. opts = opts || {};
  69. if(!Array.isArray(keys)){
  70. keys = keys.split(' ');
  71. }
  72. var indexKey = JSON.stringify(keys.sort());
  73. conf.backend.shardId = '$';
  74. var backend = backends.create(conf.backend);
  75. var indexCollName = Collection.prototype._indexCollectionName.call({name : collName}, indexKey);
  76. logger.warn('Start rebuild index %s %s', collName, indexKey);
  77. return ensureShutDown(conf.locking)
  78. .then(function(){
  79. return backend.start();
  80. })
  81. .then(function(){
  82. return backend.drop(indexCollName);
  83. })
  84. .then(function(){
  85. return backend.getAll(collName);
  86. })
  87. .then(function(itor){
  88. return utils.mongoForEach(itor, function(item){
  89. var indexValue = Document.prototype._getIndexValue.call({_getChanged : function(){return item;}}, indexKey, opts);
  90. if(!indexValue){
  91. return;
  92. }
  93. return P.try(function(){
  94. return backend.get(indexCollName, indexValue);
  95. })
  96. .then(function(doc){
  97. if(!doc){
  98. doc = {_id: indexValue, ids : []};
  99. }
  100. else if(opts.unique){
  101. throw new Error('Duplicate value for unique key ' + indexKey);
  102. }
  103. if(doc.ids.indexOf(item._id) === -1){
  104. doc.ids.push(item._id);
  105. }
  106. return backend.set(indexCollName, indexValue, doc);
  107. });
  108. });
  109. })
  110. .then(function(){
  111. logger.warn('Finish rebuild index %s %s', collName, indexKey);
  112. return backend.stop();
  113. });
  114. };