Module: Mongoid::Tasks::Database
Overview
Utility module to manage database collections, indexes, sharding, etc. Invoked from Rake tasks.
Instance Method Summary collapse
-
#create_collections(models = ::Mongoid.models, force: false) ⇒ Object
Create collections for each model given the provided globs and the class is not embedded.
-
#create_indexes(models = ::Mongoid.models) ⇒ Array<Class>
Create indexes for each model given the provided globs and the class is not embedded.
-
#create_search_indexes(models = ::Mongoid.models, wait: true) ⇒ Object
Submit requests for the search indexes to be created.
-
#remove_indexes(models = ::Mongoid.models) ⇒ Array<Class>
Remove indexes for each model given the provided globs and the class is not embedded.
-
#remove_search_indexes(models = ::Mongoid.models) ⇒ Object
Remove all search indexes from the given models.
-
#remove_undefined_indexes(models = ::Mongoid.models) ⇒ Hash{Class => Array(Hash)}
Remove indexes that exist in the database but aren’t specified on the models.
-
#shard_collections(models = ::Mongoid.models) ⇒ Array<Class>
Shard collections for models that declare shard keys.
-
#undefined_indexes(models = ::Mongoid.models) ⇒ Array<Hash>
Return the list of indexes by model that exist in the database but aren’t specified on the models.
Instance Method Details
#create_collections(models = ::Mongoid.models, force: false) ⇒ Object
Create collections for each model given the provided globs and the class is not embedded.
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/mongoid/tasks/database.rb', line 21 def create_collections(models = ::Mongoid.models, force: false) models.each do |model| if !model. || model.cyclic? model.create_collection(force: force) logger.info("MONGOID: Created collection for #{model}:") else logger.info("MONGOID: collection options ignored on: #{model}, please define in the root model.") end rescue Exception logger.error "error while creating collection for #{model}" raise end end |
#create_indexes(models = ::Mongoid.models) ⇒ Array<Class>
Create indexes for each model given the provided globs and the class is not embedded.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/mongoid/tasks/database.rb', line 42 def create_indexes(models = ::Mongoid.models) models.each do |model| next if model.index_specifications.empty? if !model. || model.cyclic? model.create_indexes logger.info("MONGOID: Created indexes on #{model}:") model.index_specifications.each do |spec| logger.info("MONGOID: Index: #{spec.key}, Options: #{spec.}") end model else logger.info("MONGOID: Index ignored on: #{model}, please define in the root model.") nil end end.compact end |
#create_search_indexes(models = ::Mongoid.models, wait: true) ⇒ Object
Submit requests for the search indexes to be created. This will happen asynchronously. If “wait” is true, the method will block while it waits for the indexes to be created.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/mongoid/tasks/database.rb', line 67 def create_search_indexes(models = ::Mongoid.models, wait: true) searchable = models.select { |m| m.search_index_specs.any? } # queue up the search index creation requests index_names_by_model = searchable.each_with_object({}) do |model, obj| logger.info("MONGOID: Creating search indexes on #{model}...") obj[model] = model.create_search_indexes end wait_for_search_indexes(index_names_by_model) if wait end |
#remove_indexes(models = ::Mongoid.models) ⇒ Array<Class>
Remove indexes for each model given the provided globs and the class is not embedded.
139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/mongoid/tasks/database.rb', line 139 def remove_indexes(models = ::Mongoid.models) models.each do |model| next if model. begin model.remove_indexes rescue Mongo::Error::OperationFailure next end model end.compact end |
#remove_search_indexes(models = ::Mongoid.models) ⇒ Object
Remove all search indexes from the given models.
155 156 157 158 159 160 |
# File 'lib/mongoid/tasks/database.rb', line 155 def remove_search_indexes(models = ::Mongoid.models) models.each do |model| next if model. model.remove_search_indexes end end |
#remove_undefined_indexes(models = ::Mongoid.models) ⇒ Hash{Class => Array(Hash)}
Remove indexes that exist in the database but aren’t specified on the models.
118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/mongoid/tasks/database.rb', line 118 def remove_undefined_indexes(models = ::Mongoid.models) undefined_indexes(models).each do |model, indexes| indexes.each do |index| key = index['key'].symbolize_keys collection = model.collection collection.indexes(session: model.send(:_session)).drop_one(key) logger.info( "MONGOID: Removed index '#{index['name']}' on collection " + "'#{collection.name}' in database '#{collection.database.name}'." ) end end end |
#shard_collections(models = ::Mongoid.models) ⇒ Array<Class>
Shard collections for models that declare shard keys.
Returns the model classes that have had their collections sharded, including model classes whose collections had already been sharded prior to the invocation of this method.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/mongoid/tasks/database.rb', line 172 def shard_collections(models = ::Mongoid.models) models.map do |model| next if model.shard_config.nil? if model. && !model.cyclic? logger.warn("MONGOID: #{model} has shard config but is embedded") next end unless model.collection.cluster.sharded? logger.warn("MONGOID: #{model} has shard config but is not persisted in a sharded cluster: #{model.collection.cluster.summary}") next end # Database of the collection must exist in order to run collStats. # Depending on server version, the collection itself must also # exist. # MongoDB does not have a command to create the database; the best # approximation of it is to create the collection we want. # On older servers, creating a collection that already exists is # an error. # Additionally, 3.6 and potentially older servers do not provide # the error code when they are asked to collStats a non-existent # collection (https://jira.mongodb.org/browse/SERVER-50070). begin stats = model.collection.database.command(collStats: model.collection.name).first rescue Mongo::Error::OperationFailure => exc # Code 26 is database does not exist. # Code 8 is collection does not exist, as of 4.0. # On 3.6 and earlier match the text of exception message. if exc.code == 26 || exc.code == 8 || exc.code.nil? && exc. =~ /not found/ then model.collection.create stats = model.collection.database.command(collStats: model.collection.name).first else raise end end stats = model.collection.database.command(collStats: model.collection.name).first if stats[:sharded] logger.info("MONGOID: #{model.collection.namespace} is already sharded for #{model}") next model end admin_db = model.collection.client.use(:admin).database begin admin_db.command(enableSharding: model.collection.database.name) rescue Mongo::Error::OperationFailure => exc # Server 2.6 fails if sharding is already enabled if exc.code == 23 || exc.code.nil? && exc. =~ /already enabled/ # Nothing else raise end end begin admin_db.command(shardCollection: model.collection.namespace, **model.shard_config) rescue Mongo::Error::OperationFailure => e logger.error("MONGOID: Failed to shard collection #{model.collection.namespace} for #{model}: #{e.class}: #{e}") next end logger.info("MONGOID: Sharded collection #{model.collection.namespace} for #{model}") model end.compact end |
#undefined_indexes(models = ::Mongoid.models) ⇒ Array<Hash>
Return the list of indexes by model that exist in the database but aren’t specified on the models.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/mongoid/tasks/database.rb', line 86 def undefined_indexes(models = ::Mongoid.models) undefined_by_model = {} models.each do |model| unless model. begin model.collection.indexes(session: model.send(:_session)).each do |index| # ignore default index unless index['name'] == '_id_' key = index['key'].symbolize_keys spec = model.index_specification(key, index['name']) unless spec # index not specified undefined_by_model[model] ||= [] undefined_by_model[model] << index end end end rescue Mongo::Error::OperationFailure; end end end undefined_by_model end |