Эффективная загрузка отношений «многие-ко-многим» в TypeORM: методы загрузки только идентификаторов

При работе с отношениями «многие ко многим» в TypeORM обычно загружаются все связанные сущности. Однако в некоторых сценариях вам может потребоваться получить идентификаторы связанных объектов только из соображений производительности. В этой статье мы рассмотрим несколько методов эффективной загрузки только идентификаторов в отношениях «многие-ко-многим» с использованием TypeORM, а также примеры кода для каждого подхода.

Методы загрузки только идентификаторов в отношениях «многие ко многим»:

  1. Использование конструктора запросов:

    const result = await connection
    .createQueryBuilder()
    .select('entity.id', 'id')
    .from(Entity, 'entity')
    .leftJoinAndSelect('entity.manyToManyRelation', 'relation')
    .getRawMany();

    Этот метод использует построитель запросов для создания запроса, который выбирает только идентификатор объекта и выполняет левое соединение с отношением «многие ко многим». Результатом будет массив объектов со свойством ID.

  2. Использование необработанных SQL-запросов:

    const result = await connection.query(`
    SELECT entity.id AS id
    FROM entity
    LEFT JOIN manyToManyRelation ON entity.id = manyToManyRelation.entityId
    `);

    Написав необработанные SQL-запросы, мы можем напрямую выбрать столбец ID из таблицы сущностей и выполнить левое соединение с отношением «многие ко многим». Результатом будет массив объектов со свойством ID.

  3. Использование Entity Manager и метаданных:

    const relationMetadata = connection.getMetadata(Entity).relations.find(relation => relation.propertyName === 'manyToManyRelation');
    const result = await connection.manager
    .createQueryBuilder()
    .relation(Entity, 'manyToManyRelation')
    .of(entity)
    .loadRawMany();
    const ids = result.map(row => row[relationMetadata.inverseEntityMetadata.primaryColumns[0].propertyName]);

    Этот метод использует Entity Manager для загрузки отношения «многие ко многим» в виде необработанных данных, а затем извлекает идентификаторы на основе метаданных отношения. Результатом будет массив идентификаторов.

  4. Использование собственного метода репозитория:

    @EntityRepository(Entity)
    class EntityRepository extends Repository<Entity> {
    async loadManyToManyRelationIds(entity: Entity): Promise<number[]> {
    const relationMetadata = this.metadata.relations.find(relation => relation.propertyName === 'manyToManyRelation');
    const result = await this.createQueryBuilder()
      .relation('manyToManyRelation')
      .of(entity)
      .loadRawMany();
    return result.map(row => row[relationMetadata.inverseEntityMetadata.primaryColumns[0].propertyName]);
    }
    }
    // Usage:
    const repository = connection.getCustomRepository(EntityRepository);
    const ids = await repository.loadManyToManyRelationIds(entity);

    Этот метод предполагает создание специального репозитория с особым методом для загрузки идентификаторов отношений «многие ко многим». Он использует тот же подход, что и предыдущий метод, но инкапсулирует его в репозиторий для возможности повторного использования.

Используя эти методы, вы можете эффективно загружать в TypeORM только идентификаторы отношений «многие-ко-многим». В зависимости от ваших предпочтений и требований проекта вы можете выбрать метод, который лучше всего соответствует вашим потребностям. При принятии решения о том, какой подход использовать, не забудьте учитывать компромисс между производительностью и сложностью кода.