GN⁺: 코드 검색의 어려움
(blog.val.town)코드 검색의 어려움
- Val Town의 현재 검색 기능은 Postgres ILIKE 기능을 기반으로 하고 있어서 검색어가 코드에 있으면 검색 결과에 포함되는 단순한 부분 문자열 검색만 지원함
- 검색 결과 랭킹이 거의 없고, 여러 단어를 포함한 검색은 잘 지원되지 않음
- 더 나은 검색 기능은 가장 많이 요청되는 기능 중 하나임
자연어 검색과 코드 검색의 차이
- 일반적인 검색 솔루션들은 영어 등 자연어를 대상으로 하기 때문에 코드 검색에는 적합하지 않음
- Stop words 제거, Stemming, Lemmatization 등의 알고리즘은 코드에는 오히려 문제를 일으킴
- 예를 들어
the
는 TypeScript에서는 stop-word가 아니라 검색하고 싶은 유효한 변수명일 수 있음 - 단어 경계도 다르고, 함수명을 stemming하는 것도 큰 의미가 없음
Postgres의 Full Text Search
- Postgres의 Full Text Search 확장은 일정 규모까지는 잘 동작하지만 대규모로 가면 성능 문제에 부딪힘
- 작은 팀에서는 인프라를 가능한 단순하게 유지하는 게 중요해서 Postgres로 모든 것을 해결하려 하지만, 현재는 싱글 노드 Postgres 클러스터의 한계에 도전하는 중
- FTS를 이용한 코드 검색 사례를 찾기 어려움
pg_trgrm을 이용한 Trigram 검색
- Trigram 검색은 코드 검색에서 성공한 사례들이 있음
- Google Code Search, GitHub 새 검색 시스템, Sourcegraph 등
- Postgres의
pg_trgrm
확장을 이용해서 검색 텍스트 컬럼에 GIN 인덱스를 만들어 Trigram 검색 지원- 정규식 검색에는 좋은 해법이지만, 자유로운 검색어에 대해서는 적절한 랭킹을 만들기 어려움
코드 검색을 위한 다양한 옵션들
- Meilisearch, Typesense, Zoekt, ParadeDB, Sonic 등 다양한 검색 엔진이 있지만 대부분 코드 검색에 특화되지는 않음
- GitHub, Sourcegraph 등의 코드 검색은 우수하지만 전담 팀과 많은 시간 투자의 결과물
- Elasticsearch는 많이 커스터마이징할 수 있지만 작은 팀에서 관리 부담이 큼
- Meilisearch는 Rust로 만들어진 ES 대안이지만 지연시간에 더 초점을 맞추고 있어 보임
- ParadeDB는 "그냥 Postgres"라며 ES와 유사한 기능을 약속하지만 아직 사용할 수 없음
GN⁺의 의견
- 현재 Val Town에서 사용하는 것처럼 초기에는 Postgres의 기본 기능만으로 코드 검색을 구현하는 것이 인프라 관리 부담을 줄일 수 있는 현명한 선택으로 보임. 하지만 서비스 규모가 커지면 전문 검색 엔진의 도입이 불가피해 보임
- 규모가 커지면 Elasticsearch 정도는 도입이 필요할 것 같지만, 이 경우에도 클라우드 관리형 서비스를 사용하는 것이 인프라 관리 부담을 덜 수 있는 방법이 될 것임
- 코드 검색에 특화된 오픈소스가 많지 않다는 점이 아쉬움. 코드 검색의 중요성이 점점 커지고 있는 만큼 앞으로는 Sourcegraph 같은 코드 검색에 특화된 오픈소스 프로젝트들이 더 활발해지면 좋겠음
- 단순 문자열 검색을 넘어, 코드의 구조적 특성을 반영한 검색 랭킹 알고리즘에 대한 연구가 필요해 보임. 예를 들어 변수명, 함수명, 주석 등을 구분해서 가중치를 다르게 주는 방식 등
- 장기적으로는 Large Language Model을 활용한 Semantic Code Search 방향으로 발전해 나갈 것으로 예상됨. 동일한 로직이라도 네이밍이나 포맷이 다른 코드를 찾아주는 시맨틱 검색이 가능해진다면 개발 생산성에 큰 도움이 될 것임
Hacker News 의견
-
Sourcegraph은 대규모 코드 검색을 다루지만, 처음 시작할 때는 인덱스 없이 실시간 검색만으로도 생각보다 오래 잘 작동함. 첫 N개 일치만 찾으면 되기 때문. 이런 것을 만드는 사람들과 대화하는 것을 환영함.
-
좋은 코드 검색 플랫폼은 삶을 훨씬 쉽게 만들어줌. Google을 떠나면 내부 코드 검색 기능이 가장 그리울 것. 다른 모든 것과 잘 통합되어 있어서 상상할 수 없음. Github 검색을 사용할 때마다 더욱 감사하게 됨. 나쁘진 않지만 일반화된 코드 검색 플랫폼을 구축하는 것은 본질적으로 훨씬 어려움.
-
새로운 개발자들에게 명시적으로 가르치지는 않지만 초기에 구축해야 할 절대적으로 중요한 기술인 기본 코드 검색 기술에 대한 지식 진행 과정:
-
Ctrl+F
사용법 배우기 -
ripgrep
으로 전환 - 선택사항이지만 강력한 명령줄 편집기 중 하나를 배우는 것이 좋음
-
ripgrep
에서grep
으로 이동하고 몇 가지 플래그 배우기 -
ripgrep
으로 할 수 있는 것에 한계가 있다는 것을 깨닫고 실제 인덱싱된 전용 코드 검색 도구로 전환
-
-
IDE와 개발 도구 제작자들은 오래전부터 코드 검색을 제대로 하려면 컴파일러 플랫폼을 개방해야 한다는 통찰력을 가지고 있었음. 좋은 코드 검색은 리팩터링 지원, 자동 완성 및 기타 일반적인 IDE 기능의 기반이 됨.
-
IBM은 Eclipse로 이것을 해냈지만 그 이후로는 그에 필적할 만한 것이 없었음. Eclipse는 구문 오류가 있는 경우에도 Java용 빠른 증분 컴파일러를 가지고 있었고, IDE의 코드 표현은 해당 컴파일러와 연결되어 있었음.
-
최근에 본 가장 흥미로운 코드 검색 접근 방식 중 하나는
septum
인데, 주변 컨텍스트의 적절한 양을 파일 단위로 가져오는 것을 목표로 함. 또 다른 것은stack-graphs
로, 전체 코드베이스에서 상징적 관계를 증분적으로 해결하려고 함. -
오픈소스 솔루션의 리더라고 생각했던
hound
가 언급되지 않아 놀람. -
Github가 이상한 토큰화 동작을 "고쳐서" 성가신 적이 있음. IDE 스타일의 find-usages 기능을 개선하고 있지만 여전히 완벽하지 않아서 "foo.bar()"에 대한 텍스트 검색을 원할 때가 있는데 이 스테밍 동작이 foo와 bar가 언급된 모든 곳을 찾아 결과를 부풀림.
-
Zoekt에 대한 그들의 손짓이 이해가 안 됨. 다른 옵션보다 "새로운 인프라 약속"이 아님. 서버와 인덱서는 단일 바이너리여서 이보다 더 간단할 수 없음. Elasticsearch보다 더 무서워할 이유가 없어 보임.
-
Oracle은 로드된 모든 PL/SQL 코드가 제시되는 USER/ALL/DBA_SOURCE 뷰를 가지고 있음. EnterpriseDB가 이를 Postgres 내부에 구현하는지, 확장으로 사용할 수 있는지 궁금함.
-
Github 검색이 훌륭하다고? 대부분의 경우 거의 쓸모없는 것 같고, 복제 + ripgrep이 훨씬 더 효율적이라고 생각함. 실제 검색보다는 UX가 끔찍한 게 문제인 것 같음.