search

7 posts
SQLite FTS5로 전문 검색 구현하기

SQLite FTS5로 전문 검색 구현하기

블로그나 문서 앱을 만들다 보면 처음에는 검색 기능을 아주 단순하게 시작하게 됩니다. 제목이나 본문에 검색어가 들어 있는지 LIKE '%검색어%'로 확인하면 되니까요. 데이터가 몇십 개일 때는 이것만으로도 충분합니다. 그런데 글이 수백 개, 수천 개로 늘어나면 느낌이 달라집니다. 검색 속도가 느려지고, 관련도 순 정렬도 어렵고, 검색 결과에서 어느 부분이 매칭됐는지 보여주기도 번거로워요. "검색"이라는 단어가 한 번 들어간 글과 본문 전체가 검색에 관한 글을 같은 수준으로 다루게 되는 것도 아쉽습니다. 이럴 때 SQLite만 쓰고

하이브리드 검색과 RRF: 키워드 검색과 의미 검색을 한 줄로 합치기

하이브리드 검색과 RRF: 키워드 검색과 의미 검색을 한 줄로 합치기

지난 두 편에서 검색의 두 갈래를 따로 살펴봤는데요. BM25 키워드 검색은 단어가 정확히 일치할 때 강하고, 의미 검색은 표현이 달라도 뜻으로 문서를 찾아줍니다. 그리고 두 글 모두 마지막에 "둘을 합치면 어떨까?"라는 떡밥을 남겨뒀죠. 키워드 검색의 정확함과 의미 검색의 유연함을 동시에 누리자는 게 하이브리드 검색(hybrid search)의 아이디어입니다. 말은 간단한데, 막상 합치려고 하면 곧바로 벽에 부딪힙니다. 두 검색기가 내놓는 점수가 완전히 다른 단위거든요. BM25는 0에서 수십까지 제한 없이 커지는 점수를 주고,

의미 검색(Semantic Search)은 어떻게 동작할까: 임베딩과 벡터 유사도

의미 검색(Semantic Search)은 어떻게 동작할까: 임베딩과 벡터 유사도

전에 BM25 랭킹 알고리즘을 다루면서 마지막에 숙제를 하나 남겨뒀는데요. "환불"로 검색하면 정작 "결제 취소"가 적힌 안내 문서를 찾지 못한다는 키워드 검색의 약점이었습니다. 두 표현은 사람이 보기엔 같은 뜻이지만, 글자가 하나도 겹치지 않으니 단어 일치에 기대는 검색은 둘을 연결하지 못해요. 😅 이 빈틈을 메우는 게 바로 의미 검색(Semantic Search)입니다. 글자가 아니라 "의미"를 기준으로 문서를 찾는 방식이죠. 요즘 챗봇, 추천, RAG(검색 증강 생성)의 바탕에 거의 빠짐없이 깔려 있는 기술이기도 합니다. 이

BM25 알고리즘: 검색 엔진은 어떻게 관련도 순으로 정렬할까

BM25 알고리즘: 검색 엔진은 어떻게 관련도 순으로 정렬할까

검색창에 단어를 넣으면 결과가 주르륵 나오는데요. 그런데 이 결과들의 "순서"는 누가 정하는 걸까요? 단순히 단어가 들어간 문서를 다 모아서 보여주기만 한다면, 정작 내가 찾던 문서는 47번째쯤에 묻혀 있을 수도 있어요. 검색이 쓸모 있으려면 가장 관련 있는 문서가 맨 위로 올라와야 합니다. 이 "관련도 순 정렬"을 책임지는 게 바로 랭킹 함수입니다. 그리고 지난 20여 년간 텍스트 검색의 사실상 표준으로 자리 잡은 랭킹 함수가 바로 BM25예요. Elasticsearch, OpenSearch, Apache Lucene, SQLit

tantivy로 시작하는 Rust 풀텍스트 검색: 스키마부터 쿼리까지

tantivy로 시작하는 Rust 풀텍스트 검색: 스키마부터 쿼리까지

데이터베이스에 LIKE '%검색어%'를 박아 쓰다 보면 한계가 금방 옵니다. 결과는 느리고, 오타에 약하고, 관련도 점수도 없습니다. 본격적으로 검색다운 검색을 붙이려면 Elasticsearch나 OpenSearch를 띄우는 게 정석이지만, 가벼운 사이드 프로젝트나 임베디드 환경에서 별도 서버까지 두기는 부담스러울 때가 있어요. tantivy는 Rust로 작성된 풀텍스트 검색 엔진 라이브러리입니다. Apache Lucene에서 영감을 받은 설계라서 한 번 배워두면 검색 엔진의 기본기를 그대로 익힐 수 있고, 별도의 데몬 없이 우리

빠른 선택 (Quick Select) 알고리즘

빠른 선택 (Quick Select) 알고리즘

빠른 선택 알고리즘은 여러 값이 주어졌을 때 k 번째로 작은 값이나 큰 값을 찾을 매우 유용한 검색 알고리즘인데요. 보통 이럴 때 정렬을 생각하지만 빠른 선택 알고리즘을 이용하면 배열을 정렬하지 않고도 빠르게 해당 원소를 찾을 수 있습니다. 알고달레에서 코딩 테스트/인터뷰 준비에 좀 더 특화된 컨텐츠를 만나보세요! 📝 아이디어 일반적으로 빠른 선택 알고리즘을 설명할 때 빠른 정렬 (Quick Sort) 알고리즘이 빠지지 않는데요. 이 두 알고리즘은 공통적으로 피봇(pivot)이라고 하는 임의의 값을 기준으로 배열을 분할하는 로직을

이진 탐색(Binary Search) 알고리즘

이진 탐색(Binary Search) 알고리즘

정렬된 데이터를 검색할 때 가장 널리 사용되는 이분 탐색(binary search)에 대해서 알아보겠습니다. 알고달레에서 코딩 테스트/인터뷰 준비에 좀 더 특화된 컨텐츠를 만나보세요! 📝 기본 개념 책으로된 영어 사전(요즘은 거의 안 쓰죠? 😓)에서 단어를 찾거나 지역 업소록에서 상호명을 어떻게 찾으시나요? 수백, 수천 페이지가 되는 이러한 책을 맨 첫 페이지부터 한 장씩 넘기면서 찾으시는 분들은 아마 없으실 것입니다. 보통은 대강 중간 쯤 어딘가를 어림잡아서 페이지를 펼쳐본 후에 찾으려는 단어나 업소명과 비교하면서 검색 범위를

Discord