如何使用 sequelize 对包含表的 jsonb 列应用 where 子句?

分享于2022年07月17日 javascript node.js postgresql sequelize.js where-clause 问答
【问题标题】:如何使用 sequelize 对包含表的 jsonb 列应用 where 子句?(how to apply where clause for included table's jsonb column using sequelize?)
【发布时间】:2022-01-27 03:23:46
【问题描述】:

我在 postgres 数据库中有 2 个表。

Table_A
--------
id BIGINT
metadata JSONB

Table_B
--------
id BIGINT
a_id BIGINT
metadata JSONB

数据

Table_A
id | metadata
1  | {'gender': 'Male', 'name': 'xyz'}

Table_B
id | a_id | metadata
1  | 1    | {'country': 'IN', 'address': 'Banglore'}
2  | 1    | {'country': 'US', 'address': 'New York'}
3  | 1    | {'country': 'IN', 'address': 'Hydrabad'}

我正在使用 sequelize 并尝试将 where cluse 应用于包含表的 jsonb 列。

示例:

let query = {
        where: {
            '$table_b.metadata.address$': 'Banglore'
        }
        include: [
            {
                model: Table_B,
                as: 'table_b'
            }
        ]
    };
    
Table_A.findAndCountAll(query).then((result)=>{
    console.log(JSON.stringify(result.rows));
}).catch((err)=>{
    console.log(err)
})

但我遇到了错误

original: error: missing FROM-clause entry for table "table_b->metadata"
  at Parser.parseErrorMessage (C:\Project\test\FilterTest\node_modules\pg-protocol\dist\parser.js:287:98)
  at Parser.handlePacket (C:\Project\test\FilterTest\node_modules\pg-protocol\dist\parser.js:126:29)
  at Parser.parse (C:\Project\test\FilterTest\node_modules\pg-protocol\dist\parser.js:39:38)
  at Socket. (C:\Project\test\FilterTest\node_modules\pg-protocol\dist\index.js:11:42)
  at Socket.emit (events.js:400:28)
  at addChunk (internal/streams/readable.js:293:12)
  at readableAddChunk (internal/streams/readable.js:267:9)
  at Socket.Readable.push (internal/streams/readable.js:206:10)
  at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {

谁能帮助如何为包含表的 jsonb 列应用 where 子句?


【解决方案1】:

试试这个方法。

const query = {
    include: [{
        model: Table_B,
        as: 'table_b',
        where: {
            metadata: {
                address: 'Banglore'
            }
        }
    }]
};

这应该适用于匹配 JSONB 字段中的属性子集。

===============================================< /p>

更新:

如果您想在顶层应用 where ,则使用 JSON.stringify 进行包装,并使用 Op.contains 对属性子集进行部分匹配。

const query = {
    where: {
        '$table_b.metadata$': {
             [Op.contains]: JSON.stringify({
                 address: 'Banglore'
             }
        })
    },
    include: [{
        model: Table_B,
        as: 'table_b'
    }]
};

  • 感谢您的回复。有什么方法可以在 root 中应用 where 子句。因为我们在原始代码中动态生成 where 子句。它适用于非 jsonb 列,但不适用于 jsonb
  • 您好,我更新了答案,请查看。
  • 如果 JSONB 列只有名为地址的属性,它将起作用。但如果它有多个带有地址的属性,它将不起作用
  • 您能详细说明什么是“带地址的多重属性”吗? (地址是数组?)您能否更新您的问题以在示例中显示,以便我可以获得正确的示例数据?
  • 问题已更新为表格数据,请检查