【问题标题】:Using Bookshelf to execute a query on Postgres JSONB array elements使用 Bookshelf 对 Postgres JSONB 数组元素执行查询
【发布时间】:2017-09-16 21:36:59
【问题描述】:

我有一个带有 jsonb 数组元素的 postgres 表,我正在尝试执行 sql 查询来提取匹配的元素。我有从 postgres 命令行界面运行的原始 SQL 查询:

select * from movies where director @> any (array ['70', '45']::jsonb[])

这将返回我正在寻找的结果(电影表中的所有记录,其中 director jsonb 元素包含输入元素中的任何元素)。

在代码中,['70, '45'] 的值将是一个动态变量,即。 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

有人可以帮忙吗?

【问题讨论】:

    标签: sql postgresql jsonb knex.js bookshelf.js


    【解决方案1】:

    正如您所注意到的,knexbookshelf 并没有为简化 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/

    【讨论】:

      【解决方案2】:

      不,您只是遇到了特定查询构建器和 ORM 的限制。

      最简单的方法是使用bookshelf.Model.queryknex.rawwhereRaw 等)。使用 AS 的别名并将您的 Bookshelf 模型子类化以添加这些别名属性(如果您关心此类事情)。

      如果您希望通过 Bookshelf 看起来干净且抽象,您只需要将 JSONB 非规范化为平面表。如果您的 JSONB 大多是扁平和简单的,这可能是最好的方法。

      如果你最终使用了大量的 JSONB(它可以是相当性能与适​​当的索引),那么 Bookshelf ORM 是浪费精力。 knex 查询构建器在处理转义、引用等方面不会浪费时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-12
        • 2018-03-29
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 1970-01-01
        • 2015-07-12
        相关资源
        最近更新 更多