TOKENLIST 결합

이 페이지에서는 스키마를 설정할 때 검색 색인에서 또는 Spanner에서 전체 텍스트 검색을 실행할 때 검색어에서 TOKENLIST를 연결하는 방법을 설명합니다.

검색 색인에서 TOKENLIST 결합

때로는 애플리케이션에서 개별 필드를 검색해야 하는 경우가 있습니다. 반면에 애플리케이션은 모든 필드에서 검색해야 할 수도 있습니다. 예를 들어 문자열 열이 두 개인 테이블에서 애플리케이션이 일치 항목이 어느 열에서 비롯되었는지 구분하지 않고 두 열을 모두 검색하도록 할 수 있습니다.

Spanner에서는 다음 두 가지 방법으로 이를 실행할 수 있습니다.

  1. 단어를 개별적으로 토큰화하고 결과 TOKENLIST 값을 연결합니다(권장).
  2. 문자열을 연결하고 결과를 토큰화합니다.

두 번째 접근 방식에는 두 가지 문제가 있습니다.

  1. Title 또는 Studio를 개별적으로 색인화하려면 결합된 TOKENLIST에 색인을 생성하는 것 외에도 동일한 텍스트가 두 번 토큰화됩니다. 이로 인해 트랜잭션에서 더 많은 리소스를 사용하게 됩니다.
  2. 구문 검색은 두 필드 모두에 적용됩니다. 예를 들어 @p"Blue Note"로 설정되면 Title='Big Blue Note' 및 Studio='Blue Note Studios'가 모두 포함된 행과 일치합니다.

첫 번째 접근 방식은 구문이 하나의 필드에만 일치하고 개별 및 결합된 TOKENLIST가 모두 색인화된 경우에만 각 문자열 필드가 한 번만 토큰화되므로 이러한 문제를 해결합니다. 각 문자열 필드는 한 번만 토큰화되지만 결과 TOKENLIST는 색인에 별도로 저장됩니다.

단어를 개별적으로 토큰화하고 TOKENLIST 값 연결

다음 예시에서는 각 단어를 토큰화하고 TOKENLIST 값을 연결합니다.

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
  Combined_Tokens TOKENLIST AS (TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens])) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

TOKENLIST 연결은 쿼리 측에서 완전히 구현할 수도 있습니다. 자세한 내용은 쿼리 측 TOKENLIST 연결을 참조하세요.

TOKENLIST_CONCAT은 전체 텍스트 검색과 하위 문자열 검색 모두에서 지원됩니다. Spanner에서는 동일한 TOKENLIST_CONCAT 호출에서 TOKENIZE_FULLTEXTTOKENIZE_SUBSTRING 같은 토큰화 유형을 혼합할 수 없습니다.

저장되지 않은 열에서 텍스트 TOKENLIST 열의 정의를 변경하여 열을 추가할 수 있습니다. 이는 TOKENLIST_CONCAT에 열을 추가할 때 유용합니다. 생성 열 표현식을 변경해도 색인의 기존 행이 백필되지 않습니다.

문자열 연결 및 결과 토큰화

다음 예시에서는 문자열을 연결하고 결과를 토큰화합니다.

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Combined_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title || " " || Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

쿼리 측 TOKENLIST 연결

연결된 TOKENLIST에 색인을 생성하면 스토리지 및 쓰기 비용이 증가한다는 단점이 있습니다. 이제 각 토큰은 원래 TOKENLIST의 게시 목록에 한 번, 결합된 TOKENLIST의 게시 목록에 한 번씩 디스크에 두 번 저장됩니다. TOKENLIST 열의 쿼리 측 연결은 이 비용을 방지하지만 쿼리에서 더 많은 컴퓨팅 리소스를 사용합니다.

여러 개의 TOKENLIST를 연결하려면 SEARCH 쿼리에서 TOKENLIST_CONCAT 함수를 사용하세요. 이 섹션에서는 다음 샘플 스키마를 사용합니다.

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);

다음 쿼리는 TitleStudio 열의 어느 곳에서나 'blue' 및 'note' 토큰이 있는 행을 검색합니다. 여기에는 Title 열에 'blue' 및 'note'가 모두 포함된 행, Studio 열에 'blue' 및 'note'가 모두 포함된 행, Title 열에 'blue'가 있고 Studio 열에 'note'가 있거나 그 반대의 행이 포함됩니다.

SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')

쓰기 측과 쿼리 측 TOKENLIST 연결은 동일한 결과를 생성합니다. 두 가지 중에서 선택할 때는 디스크 비용과 쿼리 비용 간의 절충이 이루어집니다.

또는 애플리케이션이 여러 TOKENLIST 열을 검색하고 SEARCH 함수와 함께 OR을 사용할 수 있습니다.

SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')

그러나 시맨틱스는 다릅니다. AlbumTitle_Tokens에는 'blue'가 있지만 'note'는 없고 Studio_Tokens에는 'note'가 있지만 'blue'가 없는 앨범과는 일치하지 않습니다.

다음 단계