В TypeORM, как у меня есть предварительно рассчитанное поле для сущности, основанное на других полях этой сущности? - PullRequest
0 голосов
/ 30 марта 2020

Я хочу сделать поле «рейтинг» в моей пользовательской сущности. Пользовательский объект имеет отношение к рейтинговому объекту, на Пользователе есть поле, называемое RatingReceived, которое представляет собой активную загрузку всех Рейтингов, назначенных этому Пользователю.

Я хочу, чтобы поле «рейтинг» на Пользователе было среднее значение для всех значений рейтинга, которое представляет собой поле в Rating Entity, называемое «ratingValue».

Поэтому, по сути, я хочу, чтобы это вычисление было значением каждого поля рейтинга пользователя:

ratingsReceived.reduce((acc, curr) => acc + curr.ratingValue, 0) / ratingsReceived.length

Поля, о которых идет речь, имеют рейтинг «Получено» для пользователя:

  @OneToMany(
    () => Rating,
    rating => rating.ratingTo
  )
  ratingsReceived: Rating[];

И «Значение рейтинга» для рейтинга:

  @Column('decimal')
  @Min(0)
  @Max(5)
  ratingValue: number;

1 Ответ

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

После проб и ошибок удалось создать обходной путь для этого примерно так:

// After load is called after the entity loads during find() and similar
// I placed this decorator on my User Entity
@AfterLoad()
  calculateRating = async () => {
    const result = await getRepository(Rating)
      .createQueryBuilder('ratings')
      .where('ratings."ratingToId" = :id', { id: this.id })
      .getRawAndEntities();

    const ratingsAboveZero = result?.entities?.filter(x => parseFloat(x.ratingValue));
    const count = ratingsAboveZero.length;

    if (count > 0) {
      this.rating =
        ratingsAboveZero.reduce((acc, curr) => {
          return acc + parseFloat(curr.ratingValue);
        }, 0) / count;

      this.ratingCount = count;
    } else {
      this.rating = 0;
      this.ratingCount = 0;
    }
  };
...