プロジェクトにイベント通知サービスがあります。エンティティはこのように見えます。
@Entity('event')
class Event {
@Column()
message: string;
@Column()
readAt: Date;
@ManyToOne(() => User, user => user.events)
user: User;
}
@Entity('user')
class User {
@PrimaryGeneratedColumn()
id: string;
@Column()
email: string;
@Column()
fullName: string;
@OneToMany(() => Event, event => event.user)
events: Event[];
unread: number;
}
_
クラス、User
およびEvent
は、エンティティ宣言で見て、PostgreSQLデータベースで正しく機能しているとおりに、1対多の関係を持つエンティティです。
未読イベント数を持つすべてのユーザーオブジェクトを見つける必要があります。
今のところ、イベントエンティティ内のreadAt
フィールドを使用して、そのイベントを使用してすべてのユーザーを検索し、未読イベントを手動でカウントすることでこれを実現しています。
このような:
...
const users = await this.userRepository.find({ relations: ['events'] });
users.forEach(user => {
user.unread = user.events.reduce((cnt, event) => {
if (event.readAt) { return cnt + 1; }
return cnt;
}, 0);
);
...
_
私はこれが悪い練習であることを知っています、そして、私は手動カウントではなく、Typeormの機能を使ってこれを達成できることをよく確信しています。
私ができる唯一のものは、ユーザーオブジェクト内の未読メッセージをフィルタリングすることです。
...
constructor(@InjectRepository(User) private userRepository: Repository<User>) { }
...
const found = await this.usersRepository.createQueryBuilder('user')
.leftJoinAndSelect('user.events', 'events')
.where('events.readAt is null')
.getMany();
...
_
しかし、これもその制限を持っています。未読イベントなしのユーザーオブジェクトは、このクエリによって返されません。
どんな助けにも感謝されるでしょう。
アプリはNESTJSフレームワークで作られ、すべてのコードはTypeScriptで書かれています。
前もって感謝します。
試す:
const found = await this.usersRepository.createQueryBuilder('user')
.loadRelationCountAndMap('user.unreadEventCount', 'user.events', 'event', (qb) => qb.where('event.readAt IS NULL'))
.getMany();
_
loadRelationCountAndMap
について:
1引数は、カウントがマッピングされるプロパティ名です - それは@Columnではないエンティティ上のフィールドになります。
2ndは関係名前です
3RDはクエリで使用するエイリアスです
4thは、さらにフィルタリングするオプションのQueryBuilder、readAt
_列がnullの場合にチェックしている