대대댓글창 만들기

broccoli·2021년 6월 19일
0

toy

목록 보기
1/2

ℹ️ 작업환경
db: mysql 8.x
ORM: sequelize 6.x

댓글의 댓글의 댓글....을 쓸 수 있는 댓글창을 만드려고 하는데, 댓글창의 뎁스가 어디까지인지 알수 없기 때문에 sequelize에 include를 사용할 수가 없었다. 그래서 sequelize의 옵션을 찾아봤는데...

1. sequelize Include Everything 옵션

일단 결론은..실패.

해당 과정.

Including everything이라는 부분에서 비슷한 부분이 나오는거 같아서 한번 활용해 보았다.

// Fetch all models associated with User and their nested associations (recursively)
User.findAll({ include: { all: true, nested: true }});

사이트에 위와 같은 예제가 있어서 한번 Comment모델로 테스트 해봤는데 2가지 문제가 있었음.

✅ 문제1. 일단 첫번째로 원하는 모델만을 포함할수가 없었고 모든 연관 모델들이 다 엮였음.

✅ 문제2. recursive하게 계속 nested된다고 했는데, Comment를 자기 참조하는 과정에서는 1번밖에는 참조가 안됨. 알리아스를 사용해서 Comment를 LowComment로 조회도 해봤는데, recursive하게 되지 않음. 자기참조가 아닌 모델들은 계속 참조가 되었지만, 자기 자신을 참조하는 경우는 1뎁스아래밖에는 참조 안됐음.

뭐 된다고 해도 문제1의 경우로 인해서 사용할수는 없음. 그래서 직접 raw쿼리로 짜기로함.

참고로 sequelize-hierachy라는 패키지가 있다. 재귀적으로 모델을 조회하는 것을 지원해준다고해서 sequelize 공식 사이트에서도 소개되고 있다. 하지만 sequelize 5.x에서 호환이 되고 6.x의 sequelize에서는 Bluebird이 제거됨에 따라 관련 에러가 나타나기 때문에 한번 시도만 해보고 맒.

2. raw query로 comment 조회하기

MySQL의 CTE를 통해서 재귀로 자식코멘트를 찾아서 조회한 후 백엔드에서 원하는 json모형으로 변형을 해 주었음.

아래와 같이 recursive cte (MySQL에서는 8.x부터 지원) 활용한다.

    with recursive comments_cte as (
        select 원하는 컬럼들...
        from comments c
        inner join posts p on p.id = c.postId and p.postKey='${postKey}'
        where c.upperId is null and c.isDeleted = false
        union all
        select 위에 원하는 컬럼들과 같은 순서 같은 갯수 같은 데이터형태로...
        from comments c
        inner join comments_cte cte on cte.id = c.upperId
        where c.isDeleted = false
    )
    select 최종적으로 필요한 컬럼들
    from comments_cte c
    inner join users u on u.id = c.userId
    order by lvl, id desc

참고링크

profile
🌃브로콜리한 개발자🌟

0개의 댓글