Соедините две таблицы, используя другую таблицу в sequelize - PullRequest
1 голос
/ 10 апреля 2020

У меня есть три MySQL таблицы: app, app_metadata и ecosystem.

Структура таблицы приложения:

+---------------+------------+----+---+-------+--------------+
|Field          |Type        |Null|Key|Default|Extra         |
+---------------+------------+----+---+-------+--------------+
|id             |bigint(20)  |NO  |PRI|NULL   |auto_increment|
|name           |varchar(255)|NO  |   |NULL   |              |
+---------------+------------+----+---+-------+--------------+

Структура таблицы app_metadata:

+---------------+------------+----+---+-------+--------------+
|Field          |Type        |Null|Key|Default|Extra         |
+---------------+------------+----+---+-------+--------------+
|id             |bigint(20)  |NO  |PRI|NULL   |auto_increment|
|app_id         |bigint(20)  |NO  |MUL|NULL   |              |
|tag_name       |varchar(255)|NO  |   |NULL   |              |
|tag_value      |text        |NO  |   |NULL   |              |
+---------------+------------+----+---+-------+--------------+

Структура таблицы экосистемы:

+---------------+------------+----+---+-------+--------------+
|Field          |Type        |Null|Key|Default|Extra         |
+---------------+------------+----+---+-------+--------------+
|id             |bigint(20)  |NO  |PRI|NULL   |auto_increment|
|name           |varchar(255)|NO  |   |NULL   |              |
+---------------+------------+----+---+-------+--------------+

Я хотел бы объединить app table с ecosystem table, используя tag_value column и tag_name column (только если его значение равно ecosystem_id ) из app_metadata table.

Это код, который я пытался реализовать в этом сценарии использования, но он не генерирует ожидаемый результат. Фактический результат:

{
  "apps": [
    {
      "id": 1,
      "name": "EXAMPLE",
      "appMetadata": [
        {
          "id": 1,
          "tagName": "ecosystem_id",
          "tagValue": "1",
          "appId": 1,
          "ecosystem": {
            "id": 1,
            "name": "default"
          }
        },
        {
          "id": 470,
          "tagName": "vcalmic",
          "tagValue": "2",
          "appId": 1,
          "ecosystem": {
            "id": 2,
            "name": "dc/ed1"
          }
        }
      ]
    }
  ]
}

Ожидаемый результат:

{
  "apps": [
    {
      "id": 1,
      "name": "EXAMPLE",
      "appMetadata": [
        {
          "id": 1,
          "tagName": "ecosystem_id",
          "tagValue": "1",
          "appId": 1,
          "ecosystem": {
            "id": 1,
            "name": "default"
          }
        },
        {
          "id": 470,
          "tagName": "vcalmic",
          "tagValue": "2",
          "appId": 1,
          "ecosystem": null
        }
      ]
    }
  ]
}

ИЛИ этот

{
  "apps": [
    {
      "id": 1,
      "name": "EXAMPLE",
      "ecosystem": {
         "id": 1,
         "name": "default"
       },
      "appMetadata": [
        {
          "id": 1,
          "tagName": "ecosystem_id",
          "tagValue": "1",
          "appId": 1
        },
        {
          "id": 470,
          "tagName": "vcalmic",
          "tagValue": "2",
          "appId": 1
        }
      ]
    }
  ]
}
Models.ecosystem.hasOne(Models.appMetadata, { foreignKey: 'tagValue' });
Models.appMetadata.belongsTo(Models.ecosystem, { foreignKey: 'tagValue' });

const options = {
  where: { accountId },
  include: [
    {
      model: Models.appMetadata,
      include: [{ model: Models.ecosystem }],
    }
  ]
};
const apps = await Models.app.findAll(options);

1 Ответ

0 голосов
/ 11 апреля 2020

Полагаю, вам нужно добавить обязательное: false, добавить условие where для tagValue в объекте include. Таким образом, это приносит экосистему, когда значение равно 1.

Models.ecosystem.hasOne(Models.appMetadata, { foreignKey: 'tagValue' });
Models.appMetadata.belongsTo(Models.ecosystem, { foreignKey: 'tagValue' });

const options = {
  where: { accountId },
  include: [
    {
      model: Models.appMetadata,
      include: [{ model: Models.ecosystem, required: false, where: {tagValue: 1}}],
    }
  ]
};
const apps = await Models.app.findAll(options);
...