typescript 使用树实体的重复值- NestJS + TypeORM

chhkpiq4  于 2023-03-19  发布在  TypeScript
关注(0)|答案(1)|浏览(208)

我是一个新手在后端的东西,所以也许我误解了一些东西。我想创建一个照片实体评论(另一个实体),并且这些评论可以有它自己的回复(也是一个注解实体)。我不想创建另一个表(fe. photo_comment_reply),因为reply和comment是同一个实体,并且只属于photo。为了做到这一点,我使用了树实体。我创建它如下:
photo.entity.ts

@Entity()
export class Photo {
    @PrimaryGeneratedColumn()
    public id: number;

    // other properties //

    @OneToMany(() => PhotoComment, (photoComment: PhotoComment) => photoComment.photo, { eager: true })
    public photoComments: PhotoComment[];
}

photo-comment.entity.ts

@Tree('adjacency-list')
@Entity()
export class PhotoComment {
    @PrimaryGeneratedColumn()
    public id: number;

    // other properties //

    @ManyToOne(() => Photo, (photo: Photo) => photo.photoComments, { cascade: true })
    public photo: Photo;

    @TreeParent()
    public reply: PhotoComment;

    @TreeChildren()
    public replies: PhotoComment[];
}

photos.service.ts

constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: Repository<Photo>,
    @InjectRepository(PhotoComment)
    private readonly photoCommentRepository: TreeRepository<PhotoComment>,
) {}

public getPhoto(id: number): Observable<Photo> {
    return from(this.photoRepository.findOne({ where: { id }, relations: ['photoComments.replies'] }));
}

public getComment(id: number): Observable<PhotoComment> {
    return from(this.photoCommentRepository.findOneBy({ id }));
}

public addComment(addPhotoCommentDto: AddPhotoCommentDto): Observable<PhotoComment> {
    const { properties, photoId, commentToReplyId } = addPhotoCommentDto;

    return this.getPhoto(photoId).pipe(
        take(1),
        switchMap((photo: Photo) => {
            if (commentToReplyId) {
                return this.getComment(commentToReplyId).pipe(
                    take(1),
                    switchMap((photoComment: PhotoComment) => from(this.photoCommentRepository.save({ properties, photo, reply: photoComment }))) // Saving reply to comment
                )
            }

            return from(this.photoCommentRepository.save({ properties, photo })); // Saving comment to photo
        })
    );
}

我的回复可以正确地添加到照片的特定评论中。但是,当我试图获取一张照片时,我得到了一个回复,当我的回复显示在回复数组中时,也显示在评论数组中(它们是重复的)
看起来是这样的:

{
    "id": 1,

    // other properties //

    "photoComments": [
        {
            "id": 1,
            "comment": "My comment",

            // other properties //

            "replies": [
                {
                    "id": 2, // That's good
                    "comment": "My reply"
                    // other properties //
                }
            ]
        },
        {
            "id": 2, // And this is duplicated value which I don't want. It should be only presented in "replies" array above
            "comment": "My reply",

            // other properties //

            "replies": []
        }
    ]
}

我做错了什么吗?我不认为手动过滤回复评论是一个好方法。或者我误解了树实体的工作原理?

vq8itlhq

vq8itlhq1#

我设法通过修改getPhoto方法中的TypeORM查询来处理它:

public getPhoto(id: number): Observable<Photo> {
    return from(
        this.photoRepository.findOne({
            where: {
                id,
                photoComments: {
                    reply: { id: IsNull() }, // if there is an id, then we know that's reply
                }
            },
            relations: ['photoComments', 'photoComments.replies']
        })
    );
}

相关问题