NodeJS 使用postgres在sequelize中按嵌套对象值查找

oknrviil  于 2023-08-04  发布在  Node.js
关注(0)|答案(2)|浏览(116)

我试图从一个嵌套的对象数组中通过一个值来查找,但我无法使它工作。
假设我有一个名为Forms的表,这个表有一个名为collaborator的对象数组。

collaborator: DataTypes.ARRAY(DataTypes.JSONB)

字符串
这个collaborator数组中的一个典型json对象是:

{
 "id": 4,
 "name": 'John'
}


我试图根据collaborator.name的值找到一个Form。到目前为止,我尝试了这个(从各种其他问题和谷歌搜索),但它返回null

Form.findOne({
    where: {
        'collaborator.name': 'John'
    }
})


我正在阅读这本手册从续集本身,但我觉得我做错了:https://sequelize.org/v5/manual/querying.html#json

j8yoct9x

j8yoct9x1#

您可以使用sequelize.query函数执行raw query
"sequelize": "^5.21.3"postgres:9.6,例如

import { sequelize } from '../../db';
import { Model, DataTypes, QueryTypes } from 'sequelize';

class Form extends Model {}
Form.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    collaborator: DataTypes.ARRAY(DataTypes.JSONB),
  },
  { sequelize, tableName: 'forms' },
);

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await Form.bulkCreate([
      { collaborator: [{ id: 1, name: 'teresa' }] },
      { collaborator: [{ id: 2, name: 'teng' }] },
      { collaborator: [{ id: 3, name: 'slideshowp2' }] },
      {
        collaborator: [
          { id: 4, name: 'John' },
          { id: 5, name: 'Tim' },
        ],
      },
    ]);

    // test
    const data = await sequelize.query(
      `
        SELECT id, collaborator
        FROM   forms f, jsonb_array_elements(to_jsonb(f.collaborator)) obj
        WHERE  obj->>'name' = 'John';
    `,
      { type: QueryTypes.SELECT },
    );
    console.log(JSON.stringify(data));
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

字符串
执行结果:

Executing (default): DROP TABLE IF EXISTS "forms" CASCADE;
Executing (default): DROP TABLE IF EXISTS "forms" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "forms" ("id"  SERIAL , "collaborator" JSONB[], PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'forms' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "forms" ("id","collaborator") VALUES (DEFAULT,ARRAY['{"id":1,"name":"teresa"}']::JSONB[]),(DEFAULT,ARRAY['{"id":2,"name":"teng"}']::JSONB[]),(DEFAULT,ARRAY['{"id":3,"name":"slideshowp2"}']::JSONB[]),(DEFAULT,ARRAY['{"id":4,"name":"John"}','{"id":5,"name":"Tim"}']::JSONB[]) RETURNING *;
Executing (default): SELECT id, collaborator
        FROM   forms f, jsonb_array_elements(to_jsonb(f.collaborator)) obj
        WHERE  obj->>'name' = 'John';
[{"id":4,"collaborator":[{"id":4,"name":"John"},{"id":5,"name":"Tim"}]}]


检查数据库:

node-sequelize-examples=# select * from forms;
 id |                             collaborator                             
----+----------------------------------------------------------------------
  1 | {"{\"id\": 1, \"name\": \"teresa\"}"}
  2 | {"{\"id\": 2, \"name\": \"teng\"}"}
  3 | {"{\"id\": 3, \"name\": \"slideshowp2\"}"}
  4 | {"{\"id\": 4, \"name\": \"John\"}","{\"id\": 5, \"name\": \"Tim\"}"}
(4 rows)

node-sequelize-examples=# \d+ forms
                                                Table "public.forms"
    Column    |  Type   |                     Modifiers                      | Storage  | Stats target | Description 
--------------+---------+----------------------------------------------------+----------+--------------+-------------
 id           | integer | not null default nextval('forms_id_seq'::regclass) | plain    |              | 
 collaborator | jsonb[] |                                                    | extended |              | 
Indexes:
    "forms_pkey" PRIMARY KEY, btree (id)

lc8prwob

lc8prwob2#

以下是正确的查询:

const form = await Forms.findOne({
  where: {
    collaborator: {
      name: {
        equals: 'John'
      }
    }
  }
});

字符串

相关问题