Rails嵌套jsonb查询

时间:2019-03-15 21:33:03

标签: ruby-on-rails postgresql jsonb

我有这样的活动记录对象

`<BlockExercise id: 1, type: nil, user_id: 1, number: "S51_1", status: "close", exercise_distribution: {"Day1"=>{"BN3"=>"", "SQ1"=>"", "date"=>"10/03/2019"}, "Day2"=>{"BN2"=>"", "date"=>""}, "Day3"=>{"DL1"=>"", "date"=>""}, "Day4"=>{"DL2"=>"", "SQ2"=>"", "date"=>""}, "Day5"=>{"BN1"=>"", "date"=>""}}, created_at: "2019-03-15 18:59:02", updated_at: "2019-03-15 18:59:02"> `

exercise_distribution是jsonb类型。 因为这是单个对象(行),而这里是具有唯一值的多个键(天)。我想要显示日期的键(天)或不为空。所以这里的回答将是"Day1"=>{"BN3"=>"", "SQ1"=>"", "date"=>"10/03/2019"} 如何通过sql查询或任何其他合适的方式获取此信息。

1 个答案:

答案 0 :(得分:1)

整个问题表明您正在使用JSONB,实际上应该使用关系模型并实际创建一个anti-pattern表。

  

json是新的EAV –当您需要它时是一个很好的工具,但是没有什么用   您应该将其作为首选。

虽然您可以基于JSONB列进行查询:

BlockExercise.where("(Day1->>'date' <> '') IS NOT TRUE")

数据结构的布局方式非常笨拙,因为您必须这样做:

BlockExercise.where("(Day1->>'date' <> '') IS NOT TRUE")
             .where("(Day2->>'date' <> '') IS NOT TRUE")
             # ...

另一方面,添加记录更简单,更有效。

BlockExercise.joins(:exercise_distributions)
             .where.not(date: nil)