I have got an event notification service in my project. The entities look like this.
@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;
}
The classes, User and Event, are entities with one-to-many relations as you can see in the entity declaration and are working properly with the PostgreSQL database.
I have to find all the user objects with its unread events count.
For now, I am achieving this by finding all the users with its events and counting unread events manually with the readAt field in the event entity.
Like this:
...
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);
);
...
I know this is a bad practice and I am pretty sure that I can achieve this with the TypeOrm features, not with manual counting.
The only thing I can do is filtering unread messages in the user objects.
...
constructor(@InjectRepository(User) private userRepository: Repository<User>) { }
...
const found = await this.usersRepository.createQueryBuilder('user')
.leftJoinAndSelect('user.events', 'events')
.where('events.readAt is null')
.getMany();
...
But this also has its limitation. The user objects without any unread events are not returned by this query.
Any help would be appreciated.
The app is made with the NestJs framework and all the code is written in typescript.
Thank you in advance.