使用 rails 查找空的 Postgres json 子数组
Finding empty Postgres jsob sub array using rails
我的模型上有一个 jsonb 列,其中包含(除其他外)分数数组。我想找到分数数组为空的所有记录。数据如下所示:
Model.new(results: {scores: [], other: [], info: {things: 'stuff'}})
不幸的是,尝试查询 []
转换为搜索 NULL
。
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
我该怎么做?
ActiveRecord 对 PostgreSQL 的更高级类型(范围、JSON、...)的了解和集成是不完整的,因为 AR 不理解 "results -> 'scores' = ?"
SQL 字符串,AR 只看到一个字符串(大概)包含 SQL 和一个占位符。因此,AR 在替换占位符时不理解 []
应该转换为 JSON,它只是做它总是对数组做的事情:空数组变成 NULL
,非空数组成为逗号分隔列表(用于 in (?)
结构);例如:
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
Model.where("results -> 'scores' = ?", [6,11,23]).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = 6,11,23)"
您可以通过 #to_json
调用帮助 AR 然后依靠 PostgreSQL 的自动类型转换来解决这个问题:
Model.where("results -> 'scores' = ?", [].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[]')"
Model.where("results -> 'scores' = ?", [6,11,23].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[6,11,23]')"
我的模型上有一个 jsonb 列,其中包含(除其他外)分数数组。我想找到分数数组为空的所有记录。数据如下所示:
Model.new(results: {scores: [], other: [], info: {things: 'stuff'}})
不幸的是,尝试查询 []
转换为搜索 NULL
。
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
我该怎么做?
ActiveRecord 对 PostgreSQL 的更高级类型(范围、JSON、...)的了解和集成是不完整的,因为 AR 不理解 "results -> 'scores' = ?"
SQL 字符串,AR 只看到一个字符串(大概)包含 SQL 和一个占位符。因此,AR 在替换占位符时不理解 []
应该转换为 JSON,它只是做它总是对数组做的事情:空数组变成 NULL
,非空数组成为逗号分隔列表(用于 in (?)
结构);例如:
Model.where("results -> 'scores' = ?", []).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = NULL)"
Model.where("results -> 'scores' = ?", [6,11,23]).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = 6,11,23)"
您可以通过 #to_json
调用帮助 AR 然后依靠 PostgreSQL 的自动类型转换来解决这个问题:
Model.where("results -> 'scores' = ?", [].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[]')"
Model.where("results -> 'scores' = ?", [6,11,23].to_json).to_sql
#=> "SELECT \"model\".* FROM \"model\" WHERE NOT (results -> 'scores' = '[6,11,23]')"