class NoSE::Backend::MongoBackend
A backend which communicates with MongoDB
Public Class Methods
field_path(index, field)
click to toggle source
Find the path to a given field @return [Array<String>]
# File lib/nose/backend/mongo.rb, line 126 def self.field_path(index, field) # Find the path from the hash entity to the given key field_path = index.graph.path_between index.hash_fields.first.parent, field.parent field_path = field_path.path_for_field(field) # Use _id for any primary keys field_path[-1] = '_id' if field.is_a? Fields::IDField field_path end
new(model, indexes, plans, update_plans, config)
click to toggle source
Calls superclass method
NoSE::Backend::Backend::new
# File lib/nose/backend/mongo.rb, line 11 def initialize(model, indexes, plans, update_plans, config) super @uri = config[:uri] @database = config[:database] Mongo::Logger.logger.level = ::Logger::FATAL end
rows_from_mongo(rows, index, fields = nil)
click to toggle source
Convert documens returned from MongoDB into the format we understand @return [Array<Hash>]
# File lib/nose/backend/mongo.rb, line 113 def self.rows_from_mongo(rows, index, fields = nil) fields = index.all_fields if fields.nil? rows.map! do |row| Hash[fields.map do |field| field_path = MongoBackend.field_path(index, field) [field.id, field_path.reduce(row) { |h, p| h[p] }] end] end end
Public Instance Methods
by_id_graph()
click to toggle source
MongoDB uses ID graphs for column families @return [Boolean]
# File lib/nose/backend/mongo.rb, line 21 def by_id_graph true end
generate_id()
click to toggle source
Produce a new ObjectId @return [BSON::ObjectId]
# File lib/nose/backend/mongo.rb, line 27 def generate_id BSON::ObjectId.new end
index_insert_chunk(index, chunk)
click to toggle source
Insert
a chunk of rows into an index @return [Array<BSON::ObjectId>]
# File lib/nose/backend/mongo.rb, line 76 def index_insert_chunk(index, chunk) # We only need to insert into indexes which are ID graphs fail unless index == index.to_id_graph chunk.map! do |row| row_hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) } index.all_fields.each do |field| field_path = self.class.field_path(index, field) entity_hash = field_path[0..-2].reduce(row_hash) { |h, k| h[k] } if field_path.last == '_id' entity_hash[field_path.last] = BSON::ObjectId.new else entity_hash[field_path.last] = row[field.id] end end row_hash.default_proc = nil row_hash end client[index.key].insert_many(chunk, ordered: false).inserted_ids end
index_sample(index, count)
click to toggle source
Sample a number of values from the given index
# File lib/nose/backend/mongo.rb, line 101 def index_sample(index, count) rows = client[index.to_id_graph.key].aggregate( [ { '$sample' => { 'size' => count } } ] ).to_a MongoBackend.rows_from_mongo rows, index end
indexes_ddl(execute = false, skip_existing = false, drop_existing = false)
click to toggle source
Create new MongoDB collections for each index
# File lib/nose/backend/mongo.rb, line 32 def indexes_ddl(execute = false, skip_existing = false, drop_existing = false) ddl = [] # Create the ID graphs for all indexes id_graphs = @indexes.map(&:to_id_graph).uniq id_graphs.map do |id_graph| ddl << "Create #{id_graph.key}" next unless execute collection = client.collections.find { |c| c.name == id_graph.key } collection.drop if drop_existing && !collection.nil? client[id_graph.key].create unless skip_existing end # Create any necessary indexes on the ID graphs index_keys = [] @indexes.sort_by do |index| -(index.hash_fields.to_a + index.order_fields).length end.each do |index| # Check if we already have a prefix of this index created keys = index.hash_fields.to_a + index.order_fields next if index_keys.any? { |i| i[keys.length - 1] == keys } index_keys << keys id_graph = index.to_id_graph next if id_graph == index # Combine the key paths for all fields to create a compound index index_spec = Hash[keys.map do |key| [self.class.field_path(index, key).join('.'), 1] end] ddl << "Add index #{index_spec} to #{id_graph.key} (#{index.key})" next unless execute client[id_graph.key].indexes.create_one index_spec end ddl end
Private Instance Methods
client()
click to toggle source
Create a Mongo client from the saved config
# File lib/nose/backend/mongo.rb, line 239 def client @client ||= Mongo::Client.new @uri, database: @database end