如何在存储为DB中的文本的json字段中使用Activerecord进行搜索

时间:2018-04-05 18:55:41

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

我有一个Json字段存储在DB中作为文本。

我想查找包含Harvard的记录作为这些键的值

json_data['infoOnProgram']['universityName']

我应该如何构建我在哪里搜索该Json字段的请求。

Student.where(json_data...

谢谢!

2 个答案:

答案 0 :(得分:0)

如果记录不是很多,你可以做到这一点,这将是非常昂贵的:

harvard_students = Student.map {|stud|
  hash = JSON.parse(stud.json_data)
  hash['infoOnProgram']['universityName'] == 'Harvard' ? stud : nil
}.compact

如果你有很多很多记录需要迭代,你可以用正则表达式查询限制你的列表:

简单

Student.where("json data like '%Harvard%'")

略好一点

Student.where("json data like '%infoOnProgram%universityName%Harvard%'")

问题是不知道数据的结构如何,很难创建特定的正则表达式。您可以使用限制位置和迭代来更准确地确认这些记录是您正在寻找的。

答案 1 :(得分:0)

如果您确定文本列中确实包含有效的JSON,那么您可以将其转换为jsonb(或json)并使用通常的JSON operators and functions that PostgreSQL provides

Student.where(
  "json_data::jsonb -> 'infoOnProgram' ->> 'universityName' = ?",
  'Harvard'
)

Student.where(
  'json_data::jsonb -> :info ->> :name = :uni',
  info: 'infoOnProgram',
  name: 'universityName',
  uni:  'Harvard'
)

Student.where(
  'cast(json_data as jsonb) #>> array[:path] = :uni',
  path: %w[infoOnProgram universityName],
  uni: 'Harvard'
)

这将是一个昂贵的查询,因为您将无法使用任何索引。您真的应该开始将列的类型更改为jsonb的过程,这将验证JSON,避免在查询中键入强制转换,允许索引,...