Rails 嵌套jsonb查询
Rails nested jsonb query
我有这样的活动记录对象
`<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类型。
因为这是单个对象(行),所以这里有多个具有唯一值的键(天)。我想要有日期存在或不为空的键(日)。所以这里的 anser 将是 "Day1"=>{"BN3"=>"", "SQ1"=>"", "date"=>"10/03/2019"}
我如何通过 sql 查询或任何其他合适的方式获得它。
整个问题表明您正在使用 JSONB,您应该在其中实际使用关系模型并实际创建一个 table,它是一个 anti-pattern。
json is the new EAV – a great tool when you need it, but not something
you should use as a first choice.
虽然您可以基于 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)
我有这样的活动记录对象
`<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类型。
因为这是单个对象(行),所以这里有多个具有唯一值的键(天)。我想要有日期存在或不为空的键(日)。所以这里的 anser 将是 "Day1"=>{"BN3"=>"", "SQ1"=>"", "date"=>"10/03/2019"}
我如何通过 sql 查询或任何其他合适的方式获得它。
整个问题表明您正在使用 JSONB,您应该在其中实际使用关系模型并实际创建一个 table,它是一个 anti-pattern。
json is the new EAV – a great tool when you need it, but not something you should use as a first choice.
虽然您可以基于 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)