Search for a command to run...
PGroonga는 PostgreSQL의 확장입니다. 따라서 PostgreSQL이 설치된 환경에서 PGroonga를 설치해야 합니다.
하지만, 설치과정은 운영체제/PostgreSQL의 버전마다 다르며, 복잡하기에 여기에서는 다루지 않는 대신 공식 Docker 이미지를 사용하겠습니다.
다음은 PGroonga가 포함된 PostgreSQL Docker 이미지를 실행하는 docker-compose.yml입니다.
services:
my-pgroonga:
container_name: my-pgroonga
image: groonga/pgroonga:4.0.4-alpine-18
shm_size: 128mb
env_file: .env.postgres
.env.postgres 파일에는 username, password 등 PostgreSQL 설정을 작성해주세요.
$ docker compose up -d
$ docker exec -it my-pgroonga psql -U <username>
위 명령어로 PostgreSQL를 실행하고 접속해줍니다. (다른 방법으로 PostgreSQL에 접속해도 무방합니다)
CREATE EXTENSION pgroonga;
위 쿼리로 PGroonga 확장을 활성화합니다.
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT
);
articles 테이블은 id(PK), title(제목), content(본문) 컬럼으로 구성되어 있습니다.
PGroonga는 Groonga를 인덱스 엔진에 통합합니다. 따라서 Groonga 검색엔진을 사용하기 위해서는 PGroonga의 인덱스를 생성해야 합니다.
CREATE INDEX articles_title_pgroonga_idx
ON public.articles USING pgroonga (title)
WITH (tokenizer='TokenBigram');
CREATE INDEX articles_content_pgroonga_idx
ON public.articles USING pgroonga (content)
WITH (tokenizer='TokenBigram');
articles_title_pgroonga_idx 인덱스는 title 단일 컬럼에 대해 PGroonga 인덱스를 생성합니다.articles_content_pgroonga_idx 인덱스는 content 단일 컬럼에 대해 PGroonga 인덱스를 생성합니다.토크나이저는 TokenBigram을 사용합니다. (기본 토크나이저 중에서 한국어에 가장 적합한 토크나이저입니다)
Mecab-ko토크나이저를 사용할 수도 있습니다. 해당 내용은 이후 별도의 챕터에서 자세하게 다루겠습니다.
SELECT jsonb_pretty(pgroonga_command('tokenize TokenBigram "이것은 첫 번째 기사입니다."')::jsonb);
위 명령어를 통해 tokenize 된 결과를 확인할 수 있습니다.
INSERT INTO articles (title, content) VALUES
('첫 번째 기사', '이것은 첫 번째 기사입니다.'),
('두 번째 기사', '이것은 두 번째 기사입니다.'),
('세 번째 기사', '이것은 세 번째 기사입니다.');
&@~SELECT * FROM articles
WHERE title &@~ '첫 번째' OR content &@~ '첫 번째';
-- id | title | content
-- ----+--------------+----------------------------
-- 1 | 첫 번째 기사 | 이것은 첫 번째 기사입니다.
&@~ 연산자는 PGroonga의 Full Text Search를 수행합니다.
좌항에는 검색 대상 컬럼, 우항에는 검색 키워드를 지정합니다. 또한 검색 키워드에 Groonga의 쿼리 문법을 사용할 수 있습니다.
다음은 Groonga 쿼리 문법에서 자주 사용되는 연산자입니다:
KEYWORD1 AND KEYWORD2 : AND 연산자KEYWORD1 OR KEYWORD2 : OR 연산자KEYWORD1 -KEYWORD2 : 키워드 제외 연산자여기까지 따라오시면서 뭔가 싸한 느낌이 드셨을 겁니다.
articles테이블에 검색 대상 컬럼이 늘어나면 어떻게 된다면?
위와 같은 생각을 하셨다면, 맞습니다. 매번 OR 조건으로 검색 쿼리를 작성하는 것은 매우 번거로우며, 여러 인덱스를 타야하기에 성능도 좋지 않습니다.
다행히 PGroonga는 text[] 타입에 대한 인덱스도 지원합니다. 따라서, 검색 대상 컬럼을 배열로 묶어서 하나의 인덱스로 관리할 수 있습니다.
CREATE INDEX articles_pgroonga_idx
ON public.articles USING pgroonga ((ARRAY [title, content]))
WITH (tokenizer='TokenBigram');
SELECT * FROM articles
WHERE ARRAY[title, content] &@~ '첫 번째';
위 쿼리로 title, content 컬럼을 배열로 묶어서 하나의 PGroonga 인덱스를 생성하고, title, content 컬럼을 배열로 묶어서 PGroonga 검색을 수행합니다.
이제 검색 대상 컬럼이 늘어나더라도, 하나의 인덱스와 하나의 쿼리로 검색할 수 있습니다!