ruby-on-rails - Rails 嵌套 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 类型。因为这是一个单一的对象(行),这里有多个具有唯一值的键(天)。我想要日期存在或不为空的键(天)。所以这里 anser 将是"Day1"=>{"BN3"=>"", "SQ1"=>"", "date"=>"10/03/2019"}
我如何通过 sql 查询或任何其他合适的方式得到这个。
解决方案
这整个问题表明您正在使用 JSONB,您应该实际使用关系模型并实际创建一个反模式表。
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)
推荐阅读
- java - Java - 在 Linux 上运行程序时,换行选项未按预期工作
- css - scss 定位多个 ID
- javascript - 多个日期模式的 Javascript 日期验证器
- wordpress - 如何通过 IP 地址限制完整的站点范围访问,同时通过 IP 地址提供对“wp-admin”的有限访问?
- python - 从 pyspark 导入 TensorFlow 数据
- angular - ng2-dragula 与 ngb-tabset 不兼容
- gradle - 命令行 gradle 运行成功时,IDEA 报告 build.gradle.kts 中的错误
- php - 将 id 参数传递给 Laravel 中的资源
- swift - 类型转换为 NSMutableDictionary 返回 nil
- google-drive-api - Google IFrame 不适用于“X-Frame-Options”到“SAMEORIGIN”错误