代码之家  ›  专栏  ›  技术社区  ›  Marcos Di Paolo

需要使用sequenlize解析数据库的响应

  •  0
  • Marcos Di Paolo  · 技术社区  · 3 年前

    我正在使用Node和sequenlize开发一个端点,它的唯一职责是提供逗号分隔的实体id的标签。因此,预期的反应是:

    {
        "entity1_id": ["tag1", "tag2",],
        "entity2_id": ["tag3", "tag4"],
    }
    

    我毫不费力地实现了它,但我意识到我是在for循环中实例化实体,然后请求它们的标签,这对性能来说很糟糕。 因此,我决定使用原始查询,而不是这样做:

    import { QueryTypes } from "sequelize"; 
    await this.connection.query(
      `SELECT tr.external_id, ta.name from transactions tr 
          INNER JOIN  tag_taggable tt ON tt.taggable_id = tr.id AND tt.taggable_type = '${taggableType}' 
          INNER JOIN tags ta ON tt.tag_id = ta.id WHERE tr.external_id IN ('${ids.join("','")}'
    );`, { type: QueryTypes.SELECT });
    

    其中ids是 string[] external_id 是我正在使用的实体的标识符。

    现在我得到这样的结果:

    [
      { external_id: 'entity1_id', name: 'tag1' },
      { external_id: 'entity1_id', name: 'tag2' },
      { external_id: 'entity2_id', name: 'tag3' },
      { external_id: 'entity1_id', name: 'tag4' }
    ]
    

    我一直在思考我需要做什么才能得到我之前发送的回复。SQL方面的东西??,如果没有,在JS方面最好的方法是什么??(减速器?用于?)。

    0 回复  |  直到 3 年前
        1
  •  0
  •   Marcos Di Paolo    3 年前

    对于JS方面,我提出了一个 for of 以及a reduce

    const alreadyPushedIds: string[] = [];
    const finalResult: { [key: string]: string[] } = {};
    for (const result of results) {
        if (alreadyPushedIds.includes(result.external_id)) {
            finalResult[result.external_id].push(result.tag_name);
        } else {
        alreadyPushedIds.push(result.external_id);
        Object.assign(finalResult, { [result.external_id]: [result.tag_name] });
        }
    }
    
    results.reduce<{ [key: string]: string[] }>((
          acc: { [key: string]: string[] },
          val: { external_id: string; tag_name: string }
        ) => {
          if (!acc[val.external_id]) {
            acc[val.external_id] = [];
          }
          acc[val.external_id].push(val.tag_name);
          return acc;
        }, {})