[英]Querying JSONB field on a associated model with Sequelize.js and PostgreSQL
我有两个模特Foo
和Bar
。 Foo
有一个字段barId
,因此有一个与之关联的Bar
对象。 我可以查询我所有的Foo
对象,并包括它们的相关Bar
对象(我将TypeScript与sequelize-typescript一起使用):
Foo.findAll<Foo>({
include: [{ model: Bar }]
});
Bar
对象具有结构的JSONB字段jsonb_field
{ inner_field1: 'some text', inner_field2: 'some more text' }
我可以查询Bar
对象并通过inner_field1
过滤,如下所示:
Bar.findAll<Bar>({
where: { 'jsonb_field': { inner_field1: 'text to find' } }
});
这将产生以下SQL查询:
SELECT ... FROM "Bar" AS "Bar"
WHERE ("Bar"."jsonb_field"#>>'{inner_field1}') = 'text to find'
到现在为止还挺好。 现在,让我们尝试查询Foo
对象,包括Bar
对象并通过inner_field1
过滤:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': { inner_field1: 'text to find' } },
include: [{ model: Bar }]
});
现在,这引发一个异常:
Error: Invalid value [object Object]
at Object.escape ({project_root}\node_modules\sequelize\lib\sql-string.js:50:11)
at Object.escape ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:917:22)
at Object.whereItemQuery ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:2095:41)
at _.forOwn ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:1937:25)
...
作为记录,我正确地包含Bar对象,因为我可以按其他非JSONB属性进行过滤,例如:
Foo.findAll<Foo>({
where: { '$bar.number_field$': 5 },
include: [{ model: Bar }]
});
据我所知,问题就出在Sequelize没有意识到的类型jsonb_field
所以当一个对象被传递到哪里查询引发错误。
有没有办法解决此错误,也许使用sequelize.literal()
或sequelize.json()
吗?
使用sequelize.cast
和$contains
运算符:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.cast('{ "inner_field1": "text to find" }', 'jsonb')
},
include: [{ model: Bar }]
});
或者按照您的建议使用sequelize.literal
:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.literal(`'{ "inner_field1": "text to find" }'::json`)
},
include: [{ model: Bar }]
});
两种解决方案都容易受到SQL注入的攻击,以确保转义或删除所有可能导致问题的字符( "
, '
,...)
是的,我刚刚回答了我自己的问题。 别客气。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.