【问题标题】:How do I search an array of hashes based on multiple keys in Rails Postgres?如何根据 Rails Postgres 中的多个键搜索哈希数组?
【发布时间】:2020-07-23 05:18:18
【问题描述】:

我想要一个可以输入和搜索的数组。

add_column :drinkers, :habits, :text, array: true, default: []
drinker.habits << { year: DateTime.now.year, month: DateTime.now.month, drinker_id: drinker_id, napped_at_8am: true }

如何根据多个drinker.habits 键值搜索饮酒者?

Drinker.select {|drinker| drinker[habits][:year] === 2020 && drinker[habits][:drinker_id] === 1 }

这是我的猜测,但我在任何地方都找不到关于多个键值搜索的任何信息。

【问题讨论】:

  • 这是一个非常自找的问题。不要在文本列中存储哈希。数组列中的文本要少得多。 JSON 列将是一种改进,但使用单独的表和连接表确实是这里的解决方案。
  • 您不想这样做的真正原因是,如果您将一堆序列化数据推入一个字符串类型的列,则数据将无法以任何体面的方式进行查询或索引。您在这里所做的实际上只是将所有内容从数据库中提取出来,然后在 Ruby 中对其进行反序列化和过滤。这根本无法扩展。

标签: arrays ruby-on-rails postgresql hash


【解决方案1】:

这真的只是一个典型的例子,说明数据库建模不好。

Postgres 数组对于真正专业的任务来说是一个很好的工具,其中你有一个简单的标量值数组,例如整数或字符串。如果您想存储哈希,它们不是一个好主意。如果你将一个 Ruby 散列塞进一个数组列中,你会得到一个不可查询的混乱。

JSON/JSONB 类型可以存储更复杂的结构,例如对象数组,如果数据无法确认模式,那么它是一个有效的选择。虽然您可以使用包含运算符查询对象数组:

SELECT *
FROM "drinkers"
WHERE habits @> '[{"year": 2020}]'

如果数据是结构化的,那么您在这里真的没有任何好处。一旦你提高了复杂性,查询将是可怕的,而且你也不会有任何索引来加速它们。

相反,您只想面对关系数据库是表格的事实,并且在关系数据库中建模数据的方式是 - 您猜对了 - 表格。

class Drinker < ApplicationRecord
  has_many :habits
end

class Habit < ApplicationRecord
  belongs_to :drinker
end

Drinker.joins(:habits)
       .where(habits: { year: 2020 })

TLDR; 数组、JSON/JSONB 和 hstore 是非常适合专门工作的工具。但绝不应该是你做任何事情的首选。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2016-06-27
    • 2019-05-01
    • 2017-02-15
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多