Storing nested Hashes in PostgreSQL with Rails 4 (and Hstore)

天涯浪子 提交于 2019-12-12 10:33:06

问题


I have a Rails app that aggregates a lot of data from Google API's. I store the JSON responses in MongoDB currently (so my Rails app has both pg and mongo). However, today, I've came across PostgreSQL Hstore extension, and I've decided to give it a try.

Unfortunately, I've ran into a problem. JSON given by API's is multiple levels deep, so Ruby Hash after JSON.parse contains hashes, which contain new hashes. However, Hstore is string key/value store, and it only goes 1 level deep. So hashes within first hash just become strings.

The really nasty hack I found to do is to eval the hashes that were turned into strings:

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

I do not like this. Any tips on what to do? Should I keep using MongoDB or is there any better way to store multi-level deep hashes in PG?


回答1:


You should try using JSON extension for Postgresql. It will do exactly what you want: validate and store JSON. Originally JSON extension was added in 9.2. Postgres 9.3 added more features for JSON extension including new operators and functions. And postgres 9.4 will have advanced indexing support for JSON so you'll be futureproof with this setup.

Related links: 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 is a gem that supports nested hashes (and arrays and other types) in hstores, achieving something similar to a document store like MongoDB. It uses a hybrid of hstore and JSON serialization. It hasn't been tested on Rails 4, though.




回答3:


As the documentation of Hstore states, keys and values in Hstore are simply text strings. Hstore cannot store multi-level json objects, nor is it meant for that purpose.

So to make it simple, you cannot replace MongoDb with PostgreSQL by simply using Hstore. Instead, you'll need to create tables for each kind of objects like in any other relational databases. If the schema of your objects are very dynamic, it'd be better to keep using MongoDB.




回答4:


As a followup to the question, it seems that Postgresql 9.4 has some awesome goodies to offer:

  1. Hstore is now nested and supports arrays, which means moving from simple key-value model to rich document-based model.
  2. Hstore access to specified field is fast (thanks to binary representation)
  3. Hstore operators can use GiST and GIN indexes
  4. Json users can use functional GIN index and get considerable speedup
  5. Hstore's binary representation can be used by json

source




回答5:


Use the json data type to store json, not hstore.




回答6:


If you're not interested in turning your multi-level json into objects that can be stored in postgres, you can stick everything in a text field in postgres and serialize/deserialize a json string if you're looking for a multi-level key/value storage outside of mongo.

As mentioned, Hstore doesn't do what you want.




回答7:


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


来源:https://stackoverflow.com/questions/18861724/storing-nested-hashes-in-postgresql-with-rails-4-and-hstore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!