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

标签 node.js postgresql typescript sequelize.js

我有两个模型 FooBarFoo 有一个字段 barId,因此有一个 Bar 对象与之关联。 我可以查询我所有的 Foo 对象并包括它们相关的 Bar 对象(我正在使用带有 sequelize-typescript 的 TypeScript):

Foo.findAll<Foo>({
  include: [{ model: Bar }]
});

Bar 对象有一个 JSONB 字段 jsonb_field with structure

{ 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 的类型,所以当一个对象被传递给 where 查询时它会抛出一个错误。

是否有解决此错误的方法,也许使用 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 Injections 的攻击, 以确保转义或删除所有可能导致问题的字符 (",',...)

是的,我刚刚回答了我自己的问题。不客气。

关于node.js - 使用 Sequelize.js 和 PostgreSQL 查询关联模型上的 JSONB 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46421054/

相关文章:

sql - 为什么创建表比更新字段快?

sql - 根据列的最大值从行中选择多列

javascript - Angular : Make Post Request From ErrorHandler?

javascript - 是否有与 TypeScript 中的 Spread Operator 等效的用于接口(interface)的功能?

node.js - 如何在 JEST 中的 express 中间件中测试 next()

arrays - Node.JS + MongoDB 聚合 从 MongoDB 中的数据库中查找数组中的数组

node.js - 在 'npm' 的 'dependencies' 字段中添加 'package.json' 有什么意义吗?

node.js - 无法再从 http 页面调用方法 FB.getLoginStatus

sql - 在事务中删除然后创建外键约束是否安全?

typescript - 如何将一个方法的签名复制到另一个方法?