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

10

我有一个Rails应用程序,从Google API汇总了大量数据。目前我将JSON响应存储在MongoDB中 (所以我的Rails应用程序同时具有pg和mongo)。然而,今天,我遇到了PostgreSQL Hstore扩展,并决定试一试。

不幸的是,我遇到了一个问题。由API提供的JSON具有多层结构,因此在JSON.parse之后,Ruby哈希包含哈希,这些哈希包含新哈希。但是,Hstore是一个字符串键/值存储,它只能深入1级。因此,第一个哈希内部的哈希就变成了字符串。

我发现的真正恶心的方法是对已被转换为字符串的哈希进行eval处理:

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

我不喜欢这个。有什么建议吗?我应该继续使用 MongoDB 还是有更好的方法可以在 PG 中存储多级深哈希表?

7个回答

6

Nested Hstore 是一个支持在 Hstore 中使用嵌套哈希(以及数组和其他类型)的宝石库,实现了类似于 MongoDB 文档存储的功能。它使用 Hstore 和 JSON 序列化的混合方式。尽管如此,它还没有在 Rails 4 上进行测试。


谢谢。虽然有点晚了,但这个想法很好,本来可以很好地满足我的需求的。 - if __name__ is None

6
你应该尝试使用Postgresql的JSON扩展。它将完全满足你的需求:验证并存储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

5
根据Hstore的文档,Hstore中的键和值只是文本字符串。 Hstore无法存储多级json对象,也不是其设计目的。
因此,简而言之,你不能仅通过使用Hstore来将MongoDb替换为PostgreSQL。 相反,您需要为每种对象创建表格,就像在任何其他关系型数据库中一样。 如果您的对象模式非常动态,则最好继续使用MongoDB。

4
作为问题的跟进,Postgresql 9.4有一些很棒的好处可以提供:
  1. Hstore现在是嵌套的并支持数组,这意味着从简单的键值模型转向丰富的基于文档的模型。
  2. 指定字段的Hstore访问速度很快(感谢二进制表示)
  3. Hstore运算符可以使用GiST和GIN索引
  4. Json用户可以使用功能性GIN索引并获得相当大的加速效果
  5. Hstore的二进制表示可以被json使用
来源

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

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

1
请通过描述您所做的事情以及它如何回答问题来解释此代码,以便提问者(和未来的读者)不需要请求澄清。 - bignose

1
如果您不想将多级json转换为可以存储在postgres中的对象,可以将所有内容放入postgres的text字段中,并在寻找mongo之外的多级键/值存储时对json字符串进行序列化/反序列化。正如所提到的,Hstore不能满足您的需求。

是的,我想我可以这样做。但我真的很想在数据库中有字段,而不需要模式。 - if __name__ is None
那么 MongoDB 就是为你而生的! - agmin
此外,比存储 JSON 更好的方法是使用 Rails 的 serialize 模型助手,它使用 :text 数据库字段,但可以自动将 Ruby Hash 转换为文本,反之亦然。 - if __name__ is None

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接