Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb replacing dot (.) in key name while inserting document

Tags:

ruby

mongodb

MongoDb doesn't support keys with dot. I have a Ruby nested hash that has many keys with dot (.) character. Is there a configuration that can be used to specify a character replacement for . like an underscore _ while inserting such data to MongoDb

I'm using MongoDB with Ruby & mongo gem.

example hash is like below

{
  "key.1" => {
             "second.key" => {
                             "third.key" => "val"
                           }
             }
}
like image 836
user3206440 Avatar asked Jan 08 '17 03:01

user3206440


1 Answers

If it isn't possible to use keys with . in Mongodb, you'll have to modify the input data :

hash = {
  'key.1' => {
    'second.key' => {
      'third.key' => 'val.1',
      'fourth.key' => ['val.1', 'val.2']
    }
  }
}

Transforming string keys

This recursive method transforms the keys of a nested Hash :

def nested_gsub(object, pattern = '.', replace = '_')
  if object.is_a? Hash
    object.map do |k, v|
      [k.to_s.gsub(pattern, replace), nested_gsub(v, pattern, replace)]
    end.to_h
  else
    object
  end
end

nested_gsub(hash) returns :

{
    "key_1" => {
        "second_key" => {
             "third_key" => "val.1",
            "fourth_key" => [
                "val.1",
                "val.2"
            ]
        }
    }
}

Transforming keys and values

It's possible to add more cases to the previous method :

def nested_gsub(object, pattern = '.', replace = '_')
  case object
  when Hash
    object.map do |k, v|
      [k.to_s.gsub(pattern, replace), nested_gsub(v, pattern, replace)]
    end.to_h
  when Array
    object.map { |v| nested_gsub(v, pattern, replace) }
  when String
    object.gsub(pattern, replace)
  else
    object
  end
end

nested_gsub will now iterate on string values and arrays :

{
    "key_1" => {
        "second_key" => {
             "third_key" => "val_1",
            "fourth_key" => [
                "val_1",
                "val_2"
            ]
        }
    }
}
like image 77
Eric Duminil Avatar answered Nov 15 '22 05:11

Eric Duminil