繁体   English   中英

使用Sequelize.js和PostgreSQL在关联模型上查询JSONB字段

[英]Querying JSONB field on a associated model with Sequelize.js and PostgreSQL

我有两个模特FooBar 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM