Skip to content

[테크니컬 라이팅] 새로이(강철원) 미션 제출합니다.#1046

Open
Ryan-Dia wants to merge 3 commits intowoowacourse:ryan-diafrom
Ryan-Dia:ryan-dia2
Open

[테크니컬 라이팅] 새로이(강철원) 미션 제출합니다.#1046
Ryan-Dia wants to merge 3 commits intowoowacourse:ryan-diafrom
Ryan-Dia:ryan-dia2

Conversation

@Ryan-Dia
Copy link

No description provided.

Copy link

@rladmstn rladmstn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!
검색 기능 구현을 위해 많은 부분을 고려하신 점이 돋보이는 글이었어요!

### 2) MySQL 풀텍스트 인덱스와 N-gram 파서 이해
MySQL 풀텍스트 검색을 사용하려면 풀텍스트 인덱스를 먼저 생성해야 합니다.
인덱스 없이 MATCH ... AGAINST 쿼리를 실행하면 에러가 발생하므로, 검색 대상 컬럼에 대해 미리 인덱스를 만들어두어야 합니다. 풀텍스트 인덱스는 일종의 **역색인(inverted index)**으로, 문서 내 단어들을 빠르게 찾아낼 수 있는 자료 구조입니다. 문제는 한국어였습니다. MySQL의 기본 풀텍스트 검색은 영어 등 띄어쓰기로 단어 구분이 명확한 언어에 최적화되어 있습니다. 예컨대 "My cat is cute"라는 문장이 있으면 공백을 기준으로 [My], [cat], [is], [cute] 같은 단어 토큰으로 쪼개서 인덱싱합니다. 하지만 한국어는 띄어쓰기만으로 단어 경계가 분명하지 않고, 조사나 접사가 붙어 단어 형태가 변합니다. 이런 언어에는 MySQL 8.0 이상에서 제공하는 N-gram 파서를 적용하는 것이 효과적입니다. N-gram 파서란 텍스트를 인덱싱할 때 일정 길이로 잘라서 토큰을 만드는 방식입니다. 예를 들어 2-gram(bi-gram)으로 "데이터 분석은 재미있다"라는 문장을 파싱하면 다음과 같은 토큰들이 만들어집니다:
"데이터", "이터분", "터분석", "분석은", "석은재", "은재미", "재미있", "미있다"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 예시 2-gram이 아니라 3-gram인 것 같아요!!

캐릿에서는 특정 키워드를 검색하면 해당 키워드가 제목에 포함된 콘텐츠를 최상단에 노출하고, 본문에서 해당 키워드가 가장 많이 언급된 콘텐츠를 그 다음 순위로 노출하는 방식을 취합니다


우리 서비스도 이러한 기능을 참고하여, 키워드가 많이 등장하는 콘텐츠일수록 사용자가 찾는 주제와 더 밀접할 것이라는 판단을 했습니다. 현 상태에서 우리의 검색 기능은 제목만 대상으로 검색이 이루어지고 있었습니다. 예를 들어 어떤 키워드로 검색하면 제목에 그 단어가 포함된 아티클은 잘 나오지만, 본문 내용에만 있는 경우는 검색되지 않는 한계가 있었죠. 이는 서비스 구조상 뉴스레터 아티클의 본문이 매우 길고 (하나의 아티클에 여러 주제와 많은 양의 글이 포함됨), 단순한 방법으로 본문까지 모두 검색할 경우 성능 문제가 우려되었기 때문입니다. 우선 현재 데이터를 분석해 보았습니다. 뉴스레터 아티클은 HTML 형식으로 메일이 오며, 이를 파싱하여 DB에 그대로 저장하고 있습니다. 하나의 아티클은 HTML 태그 포함 시 약 8만~16만 자 정도의 길이이고, 태그를 제거한 순수 텍스트만 약 5천~1만5천 자 수준입니다. 대략 10배 정도의 차이가 나기 때문에, 검색 시에는 불필요한 HTML 태그를 제외한 텍스트만 사용하기로 했습니다. 따라서 DB에 원본 HTML과 별도로 검색용 순수 텍스트를 함께 저장해두는 방식으로 데이터를 관리했습니다. 그래야 검색시 불필요한 태그 처리 없이 텍스트만 빠르게 검색할 수 있기 때문입니다. 그렇다고 해도 수천 자에 달하는 본문 텍스트를 대상으로 검색을 하면 부하가 만만치 않습니다. 단순히 SQL의 LIKE 연산자로 %키워드%를 검색한다면 인덱스를 탈 수 없고 테이블 전체를 훑는 식이어서, 가장 데이터가 많은 이 아티클 테이블에서는 성능 저하가 불 보듯 뻔했습니다. 검색 기능을 도입하기 전에, 서비스 특성과 데이터를 철저히 파악하고 (말 그대로 지피지기 백전불태의 마음으로) 어떤 검색 구현 방식을 선택할지 고민하기 시작했습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 중간에 ~ ~ 때문에 이렇게 되는 것 같아요!!
개행으로 문장들을 나눠주면 좋을 것 같습니다!

Comment on lines +26 to +30
> 📌 풀텍스트/N-gram 설정 체크리스트
> - `innodb_ft_min_token_size=2` (2자 이상 토큰화)
> - `ngram_token_size=2` (한글 2-gram 권장)
> - `innodb_ft_enable_stopword=OFF` 또는 커스텀 스톱워드 테이블
> - 위 설정 변경 후 **FULLTEXT 인덱스 재생성 필수**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 체크리스트 좋아요!!
간편하게 활용 고려해보기 좋네요!

Comment on lines +78 to +79
## 6. 향후 개선 방향: 형태소 분석 도입 검토
검색 기능을 고도화하는 중장기 전략으로는 한국어 형태소 분석기의 도입을 고려하고 있습니다. 현재의 N-gram 방식은 부분 검색을 가능하게 해주지만 그 대가로 인덱스 크기가 크게 늘어난다는 문제점이 있었습니다. 이를 해결하기 위해 형태소 단위로 텍스트를 분할해 인덱싱하면, 불필요한 조각을 줄이고도 충분한 검색 품질을 얻을 수 있습니다. 예를 들어 형태소 분석을 도입하면 "경제학개론"이라는 단어는 "경제학"+"개론"처럼 의미 단위로 쪼개어 인덱싱됩니다. 이렇게 하면 "경제학"으로 검색해도 해당 문서를 찾을 수 있고, "개론"으로 검색해도 연결될 수 있습니다. 불용어(조사 등)를 걸러내고 실질적인 단어만 인덱싱하기 때문에 인덱스 용량을 효율적으로 줄일 수 있고 검색 정확도도 높아집니다. 이미 일부 오픈소스 형태소 분석 플러그인(예: MeCab-ko 등)을 MySQL과 연동하는 사례도 있습니다. 다만 AWS RDS와 같은 관리형 DB 환경에서는 사용자가 직접 플러그인을 설치할 수 없다는 제약이 있습니다. 따라서 이를 활용하려면 별도의 MySQL 서버를 구성하거나, 아예 Elasticsearch 등의 전문 검색엔진으로 전환해야 합니다. 현 시점에서는 우리 서비스 규모에 비해 과한 작업이기 때문에 도입하지 않았지만, 추후 트래픽이 크게 증가하고 검색 수요가 늘어난다면 형태소 분석 기반의 검색으로 업그레이드하는 것도 고려하고 있습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

향후 개선 방향에 대해서도 언급해주신 점 좋은 것 같아요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants