Хранение вложенных хэшей в PostgreSQL с Rails 4 (и Hstore)

У меня есть приложение Rails, которое собирает много данных из API Google. Я храню ответы JSON в MongoDB в настоящее время (так что мое приложение Rails имеет как pg, так и mongo). Однако сегодня я столкнулся с расширением PostgreSQL Hstore, и я решил попробовать.

К сожалению, у меня возникла проблема. JSON, предоставляемый API, имеет несколько уровней, поэтому Ruby Hash после JSON.parse содержит хеши, содержащие новые хэши. Тем не менее, Hstore - это хранилище строк/значений, и оно идет только на 1 уровень. Так что хэши внутри первого хэша просто становятся строками.

Действительно неприятный хак, который я нашел, - это eval хэши, которые были превращены в строки:

eval("{ "foo" => "bar" }")

Мне это не нравится. Любые советы о том, что делать? Должен ли я продолжать использовать MongoDB или есть лучший способ хранить многоуровневые глубокие хэши в PG?

Ответ 1

Вам следует попробовать использовать расширение JSON для Postgresql. Он будет делать именно то, что вы хотите: проверить и сохранить JSON. Первоначально расширение JSON было добавлено в 9.2. Postgres 9.3 добавил дополнительные функции для расширения JSON, включая новые операторы и функции. И postgres 9.4 будут иметь расширенную поддержку индексирования JSON, чтобы вы были в будущем надежными с этой настройкой.

Ссылки по теме: http://www.postgresql.org/docs/9.3/static/functions-json.html http://wiki.postgresql.org/wiki/What 's_new_in_PostgreSQL_9.3 # JSON: _Additional_functionality

Ответ 2

Nested Hstore - это жемчужина, которая поддерживает вложенные хэши (и массивы и другие типы) в hstores, достигая чего-то подобного хранилищу документов, такого как MongoDB, Он использует гибрид сериализации hstore и JSON. Однако он не тестировался на Rails 4.

Ответ 3

Как документация состояний Hstore, ключи и значения в Hstore являются просто текстовыми строками. Hstore не может хранить многоуровневые json-объекты и не предназначен для этой цели.

Итак, чтобы сделать его простым, вы не можете заменить MongoDb на PostgreSQL, просто используя Hstore. Вместо этого вам нужно будет создавать таблицы для каждого типа объектов, как в любых других реляционных базах данных. Если схема объектов очень динамична, лучше использовать MongoDB.

Ответ 4

В качестве ответа на вопрос, похоже, что Postgresql 9.4 предлагает некоторые потрясающие плюсы:

  • Hstore теперь вложен и поддерживает массивы, что означает переход от простой модели ключевого значения к богатой модели на основе документов.
  • Доступ к HSTOR в указанное поле выполняется быстро (благодаря двоичному представлению)
  • Операторы Hstore могут использовать индексы GiST и GIN
  • Пользователи Json могут использовать функциональный индекс GIN и получать значительное ускорение
  • Бинарное представление Hstore может использоваться json

источник

Ответ 5

Используйте тип данных json для хранения json, а не hstore.

Ответ 6

Если вам не интересно превращать ваш многоуровневый json в объекты, которые можно сохранить в postgres, вы можете вставлять все в поле text в postgres и сериализовать/десериализовать строку json, если вы ищете многоуровневое хранилище ключей/значений за пределами монго.

Как уже упоминалось, Hstore не делает то, что вы хотите.

Ответ 7

setting[:quizzes] # => "{:score=>true, :percent=>true, :weight=>true}"
JSON.parse setting[:quizzes].gsub(/:(\w+)/){"\"#{$1}\""}.gsub('=>', ':')
# => {"score"=>true, "percent"=>true, "weight"=>true}