RUM 색인 만들기 및 관리

이 문서에서는 RUM 확장 프로그램을 만들고 PostgreSQL용 AlloyDB에서 전체 텍스트 검색을 최적화하기 위해 색인을 만드는 방법을 보여줍니다. 순위 지정, 구문 검색, 타임스탬프별 정렬 등 일반적인 사용 사례의 예를 제공합니다.

시작하기 전에

RUM 확장 프로그램을 만들려면 alloydbsuperuser 데이터베이스 역할이 있어야 합니다.

AlloyDB 관리자 (roles/alloydb.admin) IAM 역할은 AlloyDB 리소스에 대한 전체 제어 권한을 부여하지만 alloydbsuperuser 데이터베이스 역할은 부여하지 않습니다. 확장 프로그램을 만들려면 관리자가 alloydbsuperuser 데이터베이스 역할을 명시적으로 부여해야 합니다.

역할 부여에 관한 자세한 내용은 클러스터에 IAM 사용자 또는 서비스 계정 추가를 참고하세요.

RUM 확장 프로그램 만들기

데이터베이스당 한 번 RUM 확장 프로그램을 만들어야 합니다.

  1. psql 또는 다른 클라이언트를 사용하여 AlloyDB 데이터베이스에 연결합니다. 자세한 내용은 클러스터 인스턴스에 연결을 참고하세요.
  2. 다음 SQL 명령어를 실행하여 확장 프로그램을 만듭니다.

    CREATE EXTENSION IF NOT EXISTS rum;
    

RUM 색인 만들기

전체 텍스트 검색 쿼리를 최적화하려면 데이터에 RUM 색인을 만드세요. RUM은 다양한 사용 사례를 위한 여러 연산자 클래스를 제공합니다.

RUM 연산자 클래스 유형

다음 표에는 다양한 RUM 연산자 클래스와 기본 사용 사례가 요약되어 있습니다.

연산자 클래스 주요 사용 사례 제한사항
rum_tsvector_ops 순위 지정 및 구문 검색이 포함된 표준 전체 텍스트 검색입니다. 해당 사항 없음
rum_tsvector_hash_ops 전체 텍스트 검색을 위한 더 작은 색인과 더 빠른 업데이트 접두사 검색을 지원하지 않습니다.
rum_tsvector_addon_ops 다른 열을 기준으로 정렬된 전체 텍스트 검색 해당 사항 없음
rum_anyarray_ops 배열 열 내에서 검색 해당 사항 없음
rum_<TYPE>_ops 거리 기반 쿼리를 위한 스칼라 유형 색인 생성 해당 사항 없음
rum_tsvector_hash_addon_ops 다른 열을 기준으로 정렬된 해시 기반 전체 텍스트 검색 접두사 일치를 지원하지 않습니다.
rum_tsquery_ops 역방향 검색을 위해 저장된 tsquery 값을 색인화합니다. 해당 사항 없음
rum_anyarray_addon_ops 다른 열을 기준으로 정렬된 배열 검색 해당 사항 없음

빠른 순위 지정 및 구문 검색 기능이 필요한 표준 텍스트 검색에는 rum_tsvector_ops 연산자 클래스를 사용합니다. 이 연산자 클래스는 색인에 있는 각 형태소의 위치를 저장합니다. 다음 예시에서는 content 열이 있는 documents이라는 테이블을 만듭니다.

  1. documents이라는 테이블을 만듭니다.

    CREATE TABLE documents (
      id SERIAL PRIMARY KEY,
      title TEXT NOT NULL,
      content TEXT NOT NULL,
      published_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );
    
  2. 샘플 데이터로 documents 테이블을 채웁니다.

    INSERT INTO documents (title, content) VALUES
      ('Title', 'This search engine is working as intended');
    
  3. 표에 생성된 tsvector 열을 추가합니다. 이 열은 처리된 텍스트를 자동으로 저장하고 쿼리 성능을 개선합니다.

    ALTER TABLE documents
    ADD COLUMN search_vector tsvector
    GENERATED ALWAYS AS (to_tsvector('english', content)) STORED;
    
  4. search_vector 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum
    ON documents
    USING rum (search_vector rum_tsvector_ops);
    
  5. 색인을 사용하여 테이블을 쿼리합니다. <=> 연산자는 색인에서 직접 문서와 쿼리 간의 관련성 점수 또는 거리를 계산하여 빠른 정렬을 지원합니다.

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'search <-> engine')
    ORDER BY search_vector <=> to_tsquery('english', 'search <-> engine');
    
  6. documents 테이블을 더 많은 데이터로 채웁니다.

    INSERT INTO documents (title, content) VALUES ('Title1', 'English is my primary language.');
    INSERT INTO documents (title, content) VALUES ('Title2', 'Google has a great engineering culture');
    
  7. 접두사 검색어를 실행합니다. 이렇게 하면 eng로 시작하는 단어(예: engineer 또는 english)가 포함된 문서가 검색됩니다.

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'eng:*');
    

rum_tsvector_hash_ops 연산자 클래스를 사용하여 색인 크기를 줄이고 업데이트 속도를 개선합니다. 이 클래스는 전체 형태소 대신 각 형태소의 해시를 저장합니다. 이 접근 방식을 사용하면 색인이 작아지지만 접두사 검색은 지원하지 않습니다. 다음 예시에서는 search_vector 열이 있는 documents이라는 테이블이 있다고 가정합니다.

  1. 해시 연산자 클래스를 사용하여 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_hash
    ON documents
    USING rum (search_vector rum_tsvector_hash_ops);
    
  2. documents 테이블을 더 많은 데이터로 채웁니다.

    INSERT INTO documents (title, content) VALUES ('Title3', 'That person was driving incredibly fast, however the routing was not very efficient');
    
  3. 표준 일치 쿼리를 실행합니다.

    SELECT * FROM documents WHERE search_vector @@ to_tsquery('english', 'fast & efficient');
    
    

타임스탬프로 정렬된 검색 색인

rum_tsvector_addon_ops 연산자 클래스를 사용하여 텍스트로 필터링하고 타임스탬프와 같은 다른 필드로 정렬하는 쿼리를 최적화합니다. 이 패턴은 추가 필드의 값을 색인에 직접 저장하므로 검색 후 느린 정렬 작업을 방지합니다. 다음 예시에서는 search_vector 열과 published_at 열이 있는 documents이라는 테이블이 있다고 가정합니다.

  1. published_at 타임스탬프가 포함된 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. engine라는 단어가 포함된 문서를 찾고 발행일별로 정렬하는 쿼리를 실행합니다. 색인은 검색과 정렬을 모두 효율적으로 처리합니다.

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

rum_anyarray_ops 연산자 클래스를 사용하여 태그 목록과 같은 배열 열을 색싱합니다. 이를 통해 다른 배열과 겹치거나 (&&) 다른 배열을 포함하거나(@>) 다른 배열에 포함되는 (<@) 배열을 효율적으로 쿼리할 수 있습니다. 다음 예시에서는 tags 열을 documents 테이블에 추가합니다.

  1. tags 열을 추가하고 데이터를 입력합니다.

    ALTER TABLE documents 
    ADD COLUMN tags TEXT[];
    
    INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );
    
  2. tags이라는 TEXT[] 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_tags_rum
    ON documents
    USING rum (tags rum_anyarray_ops);
    
  3. 태그에 ai 또는 ml이 있는 문서를 찾으려면 다음 쿼리를 실행합니다.

    SELECT * FROM documents WHERE tags && '{"ai", "ml"}';
    

스칼라 유형의 색인

rum_<TYPE>_ops 연산자 클래스를 사용하여 정수, 타임스탬프, 부동 소수점 숫자와 같은 연속 값을 포함하는 열을 색인화합니다. 이러한 연산자 클래스를 사용하면 <=> 연산자를 사용하여 값 간의 거리를 효율적으로 계산할 수 있습니다. 다음 예시에서는 documents이라는 테이블이 있다고 가정합니다.

  1. documents 테이블에 rating와 같은 일반 정수 열을 추가합니다.

    ALTER TABLE documents
    ADD COLUMN rating INT;
    
    UPDATE documents 
    SET rating = floor(random() * 5 + 1);
    
  2. rating 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_rating_rum
    ON documents
    USING rum (rating rum_int4_ops);
    
  3. rating 값이 5에 가장 가까운 문서를 찾기 위해 쿼리를 실행합니다.

    SELECT title, rating
    FROM documents
    ORDER BY rating <=> 5;
    

타임스탬프별로 정렬된 최적화된 해시 검색의 색인

rum_tsvector_hash_addon_ops 연산자 클래스를 사용하여 해시 색인의 이점과 부가기능 색인의 정렬 기능을 결합합니다. 이 클래스는 추가 열의 값과 함께 각 형태소의 해시를 저장합니다. 이 구성은 추가 열을 기준으로 효율적인 정렬을 지원하지만 접두사 일치는 지원하지 않습니다. 다음 예시에서는 search_vector 열과 published_at 타임스탬프 열이 있는 documents이라는 테이블이 있다고 가정합니다.

  1. 해시 연산자 클래스를 사용하고 published_at 타임스탬프를 포함하는 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_hash_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_hash_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. engine가 포함된 문서를 찾아 발행일로 정렬하는 쿼리를 실행합니다.

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

저장된 쿼리의 색인

rum_tsquery_ops 연산자 클래스를 사용하여 tsquery 값을 색인화합니다. 이를 통해 저장된 쿼리 중 지정된 입력 문서와 일치하는 쿼리를 식별하는 '역방향 검색'을 실행할 수 있습니다. 다음 예시에서는 queries이라는 테이블을 만듭니다.

  1. 쿼리를 저장할 테이블을 만듭니다.

    CREATE TABLE queries (
    query_text tsquery
    );
    INSERT INTO queries (query_text) VALUES (plainto_tsquery('AlloyDB is fast!'));
    
  2. query_text 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_queries_rum
    ON queries
    USING rum (query_text rum_tsquery_ops);
    
  3. 문서와 일치하는 저장된 쿼리를 찾기 위해 쿼리를 실행합니다.

    SELECT *
    FROM queries
    WHERE to_tsvector('english', 'AlloyDB is fast') @@ query_text;
    

타임스탬프별로 정렬된 배열 검색의 색인

rum_anyarray_addon_ops 연산자 클래스를 사용하여 정렬을 위한 추가 열과 함께 배열 열을 색인화합니다. 다음 예에서는 tags 열과 published_at 타임스탬프 열이 있는 documents이라는 테이블이 있다고 가정합니다.

  1. published_at 타임스탬프가 포함된 tags 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_tags_rum_timestamp
    ON documents
    USING rum (tags rum_anyarray_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'tags');
    
  2. 다음과 같이 ai 태그가 있는 문서를 발행일 순으로 정렬하여 찾는 쿼리를 실행합니다.

    SELECT title, published_at
    FROM documents
    WHERE tags @> '{"ai"}'
    ORDER BY published_at DESC;
    

다음 단계