我有一个带有jsonb数组元素的postgres表,我正在尝试执行sql查询来提取匹配元素。我有从postgres命令行界面运行的原始SQL查询:
select * from movies where director @> any (array ['70', '45']::jsonb[])
这将返回我正在寻找的结果(导演jsonb元素包含input元素中任何元素的movies表中的所有记录)。
在代码中,['70,'45']的值将是动态变量ie。 fixArr和数组的长度未知。
我正在尝试将其构建到我的Bookshelf代码中,但未能找到解决用例复杂性的任何示例。我尝试了以下方法,但没有一种方法有效:
models.Movies.where('director', '@> any', '(array' + JSON.stringify(fixArr) + '::jsonb[])').fetchAll()
ERROR: The operator "@> any" is not permitted
db.knex.raw('select * from movies where director @> any(array'+[JSON.stringify(fixArr)]+'::jsonb[])')
ERROR: column "45" does not exist
models.Movies.query('where', 'director', '@>', 'any (array', JSON.stringify(fixArr) + '::jsonb[])').fetchAll()
ERROR: invalid input syntax for type json
任何人都可以帮忙吗?
答案 0 :(得分:0)
正如您所注意到的那样,knex
和bookshelf
并没有为简化jsonb查询提供任何支持。据我所知,唯一支持jsonb查询的基于knex的ORM很好Objection.js
在你的情况下,我想更好的运算符来查找jsonb列是否包含任何给定值?|
,所以查询将如下:
const idsAsString = ids.map(val => `'${val}'`).join(',');
db.knex.raw(`select * from movies where director \\?| array[${idsAsString}]`);
有关如何使用knex处理jsonb查询和索引的更多信息,请访问https://www.vincit.fi/en/blog/objection-js-postgresql-power-json-queries/
答案 1 :(得分:0)
不,您只是遇到了特定查询构建器和ORM的限制。
最简单的方法是使用bookshelf.Model.query
和knex.raw
(whereRaw
等)。带有AS
的别名,如果要考虑此类事情,可以将Bookshelf模型子类化以添加这些别名属性。
如果您希望东西看起来很整洁并且可以通过书架抽象,则只需将JSONB规范化为平面表即可。如果您的JSONB大多扁平而简单,这可能是最好的方法。
如果最终使用大量JSONB(可以使用适当的索引在相当中表现出色),那么书架ORM就会浪费很多精力。 knex查询构建器在处理转义,引用等方面不仅仅浪费时间。