find_by 和 json 数组使用 IN 执行查询而不是搜索整个数组
find_by with json array executing a query with IN instead of searching for the whole array
我有一个带有 jsonb 字段(坐标)的模型(区域):
create_table "areas" do |t|
t.jsonb "coordinates"
end
现在如果我插入一个数组:
Area.create(coordinates: [1, 2])
它工作正常,但正在搜索它:
Area.find_by(coordinates: [1, 2])
使用 IN 执行 SQL 查询,例如:
SELECT "areas".* FROM "areas" WHERE "areas"."coordinates" IN (, ) LIMIT [["coordinates", "1"], ["coordinates", "2"], ["LIMIT", 1]]
我尝试搜索 [[1, 2]]
和 [[[1, 2]]]
,但我总是得到 IN
查询。
(可能是 rails 问题)
这是您要找的吗?
Area.find_by("coordinates = '[1, 2]'")
查询 JSON/Array/Hstore 类型的列时必须使用 SQL 字符串。例如:
Event.where("payload->>'kind' = ?", "user_renamed")
它们不是查询界面的 "native" 部分,因为由于键入和不同的实现,创建查询比普通列要复杂得多。 ActiveRecord 只会为这些类型创建查询,就好像它在它理解的普通列类型中一样。参见 Active Record and PostgreSQL。
查询 json 列中的数组可以通过以下方式完成:
WHERE coordinates @> ANY (ARRAY [1,2,3]::jsonb[]);
但是 - 也许您应该重新考虑使用 JSON 列是否是一个好主意,因为查询会很糟糕? JSON/JSONB 类型适用于某些特殊任务,在这些任务中数据不符合模式,但不应替代正确的关系数据库建模。不必要 JSONB 是反模式。
此外,如果这些是地理坐标,则您将这些数字表示为整数或浮点数,但除了添加 .
之外,无法在 JSON 中指定类型,解析器如果2.0
是浮点数或整数。
如果您为坐标设置单独的 table,您实际上可以使用和使用 ActiveRecord 关联,并具有一定程度的数据规范化、索引、引用完整性等。哦,我有没有提到你实际上可以像一个正常人一样查询你的数据?
class Area
has_many :coordinates
end
# rails g model coordinate area:references lat:decimal lng:decimal
class Cooridinate
belongs_to :area
end
Area.joins(:coordinates).where(coordinates: { lat: 1, lng: 1 })
您还可以使用 PostGIS extension,它为坐标、多边形和其他类型的地理信息提供专门的列类型。
我有一个带有 jsonb 字段(坐标)的模型(区域):
create_table "areas" do |t|
t.jsonb "coordinates"
end
现在如果我插入一个数组:
Area.create(coordinates: [1, 2])
它工作正常,但正在搜索它:
Area.find_by(coordinates: [1, 2])
使用 IN 执行 SQL 查询,例如:
SELECT "areas".* FROM "areas" WHERE "areas"."coordinates" IN (, ) LIMIT [["coordinates", "1"], ["coordinates", "2"], ["LIMIT", 1]]
我尝试搜索 [[1, 2]]
和 [[[1, 2]]]
,但我总是得到 IN
查询。
(可能是 rails 问题)
这是您要找的吗?
Area.find_by("coordinates = '[1, 2]'")
查询 JSON/Array/Hstore 类型的列时必须使用 SQL 字符串。例如:
Event.where("payload->>'kind' = ?", "user_renamed")
它们不是查询界面的 "native" 部分,因为由于键入和不同的实现,创建查询比普通列要复杂得多。 ActiveRecord 只会为这些类型创建查询,就好像它在它理解的普通列类型中一样。参见 Active Record and PostgreSQL。
查询 json 列中的数组可以通过以下方式完成:
WHERE coordinates @> ANY (ARRAY [1,2,3]::jsonb[]);
但是 - 也许您应该重新考虑使用 JSON 列是否是一个好主意,因为查询会很糟糕? JSON/JSONB 类型适用于某些特殊任务,在这些任务中数据不符合模式,但不应替代正确的关系数据库建模。不必要 JSONB 是反模式。
此外,如果这些是地理坐标,则您将这些数字表示为整数或浮点数,但除了添加 .
之外,无法在 JSON 中指定类型,解析器如果2.0
是浮点数或整数。
如果您为坐标设置单独的 table,您实际上可以使用和使用 ActiveRecord 关联,并具有一定程度的数据规范化、索引、引用完整性等。哦,我有没有提到你实际上可以像一个正常人一样查询你的数据?
class Area
has_many :coordinates
end
# rails g model coordinate area:references lat:decimal lng:decimal
class Cooridinate
belongs_to :area
end
Area.joins(:coordinates).where(coordinates: { lat: 1, lng: 1 })
您还可以使用 PostGIS extension,它为坐标、多边形和其他类型的地理信息提供专门的列类型。