使用Rails 4(和Hstore)在PostgreSQL中存储嵌套的哈希

时间:2013-09-17 23:50:17

标签: ruby-on-rails postgresql ruby-on-rails-4 hstore

我有一个Rails应用程序,它聚合了来自Google API的大量数据。我目前在MongoDB中存储JSON响应(所以我的Rails应用程序同时包含pg和mongo)。但是,今天,我遇到了PostgreSQL Hstore扩展,我决定尝试一下。

不幸的是,我遇到了一个问题。 API提供的JSON是多层次的,因此JSON.parse之后的Ruby Hash包含哈希,其中包含新的哈希值。但是,Hstore是字符串键/值存储,它只有1级深度。所以第一个哈希中的哈希就变成了字符串。

我发现真正令人讨厌的黑客行为是eval变成字符串的哈希:

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

我不喜欢这个。有关怎么做的提示?我应该继续使用MongoDB还是有更好的方法在PG中存储多级深度哈希?

7 个答案:

答案 0 :(得分:6)

您应该尝试为Postgresql使用JSON扩展。它将完全符合您的要求:验证并存储JSON。最初在9.2中添加了JSON扩展。 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

答案 1 :(得分:6)

Nested Hstore是一个支持hstores中嵌套哈希(以及数组和其他类型)的gem,实现类似MongoDB之类的文档存储。它使用hstore和JSON序列化的混合。但是,它尚未在Rails 4上进行过测试。

答案 2 :(得分:4)

正如Hstore的documentation所述,Hstore中的键和值只是文本字符串。 Hstore不能存储多级json对象,也不能用于此目的。

所以为了简单起见,你不能只使用Hstore就可以用PostgreSQL替换MongoDb。相反,您需要为每种对象创建表,就像在任何其他关系数据库中一样。如果对象的模式非常动态,那么继续使用MongoDB会更好。

答案 3 :(得分:4)

作为问题的后续内容,似乎Postgresql 9.4提供了一些很棒的好东西:

  
      
  1. Hstore现在已嵌套并支持数组,这意味着从简单的键值模型转移到基于文档的丰富模型。
  2.   
  3. 对指定字段的Hstore访问速度很快(多亏二进制表示)
  4.   
  5. Hstore运算符可以使用GiST和GIN索引
  6.   
  7. Json用户可以使用功能GIN索引并获得相当快的速度
  8.   
  9. Hson的二进制表示可以由json
  10. 使用   

source

答案 4 :(得分:2)

使用json数据类型存储json,而不是hstore。

答案 5 :(得分:1)

如果你对将多级json转换为可以存储在postgres中的对象不感兴趣,你可以将所有内容都放在postgres中的text字段中,如果你是的话,可以序列化/反序列化json字符串寻找mongo之外的多级键/值存储。

如前所述,Hstore没有做你想做的事。

答案 6 :(得分:1)

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