이 페이지에서는 전체 텍스트 및 비텍스트 데이터가 혼합된 검색을 수행하는 방법을 설명합니다.
전체 텍스트 및 비텍스트 검색 수행
검색 색인은 전체 텍스트, 일치검색, 숫자 열, JSON/JSONB 열을 지원합니다. 다중 열 검색 쿼리와 마찬가지로 WHERE 절에서 텍스트 및 비텍스트 조건을 조합할 수 있습니다. 쿼리 옵티마이저는 검색 색인을 사용해서 비텍스트 조건자를 최적화하려고 시도합니다. 불가능하면 Spanner가 검색 색인과 일치하는 모든 행에 대해 조건을 평가합니다. 검색 색인에 저장되지 않은 참조 열은 기본 테이블에서 가져옵니다.
Rating 및 Genres가 검색 색인에 포함됩니다.
Spanner가 검색 색인 게시 목록을 사용하여 조건을 가속화합니다. ARRAY_INCLUDES_ANY, ARRAY_INCLUDES_ALL은 GoogleSQL 함수이며 PostgreSQL 언어에서는 지원되지 않습니다.
Likes는 색인에 저장되지만 스키마에 따라 Spanner에서 가능한 값에 대한 토큰 색인 빌드가 요청되지 않습니다.
따라서 Title의 전체 텍스트 조건자와 Rating의 비텍스트 조건자가 가속화되지만 Likes의 조건자는 가속화되지 않습니다. Spanner에서 쿼리는 Title에 "car"가 있고 평점이 4보다 높은 모든 문서를 가져온 후 좋아요가 1,000개 미만인 문서를 필터링합니다. 거의 모든 앨범의 제목에 "car"가 있고 거의 대부분 평점이 5이지만 좋아요가 1,000개 있는 앨범이 많지 않으면 이 쿼리에 많은 리소스가 사용됩니다. 이러한 경우 Rating과 비슷하게 Likes를 색인 생성하면 리소스가 절약됩니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-03(UTC)"],[],[],null,["# Mix full-text and non-text queries\n\n| **Note:** This feature is available with the Spanner Enterprise edition and Enterprise Plus edition. For more information, see the [Spanner editions overview](/spanner/docs/editions-overview).\n\n\u003cbr /\u003e\n\nThis page describes how to perform a search that mixes full-text and non-text\ndata.\n\nPerform a mixed full-text and non-text search\n---------------------------------------------\n\n[Search indexes](/spanner/docs/full-text-search/search-indexes) support\nfull-text, exact match, numeric columns, and JSON/JSONB columns. You can combine\ntext and non-text conditions in the `WHERE` clause similarly to multi-column\nsearch queries. The query optimizer tries to optimize non-text predicates with a\nsearch index. If that's not possible, Spanner evaluates the\ncondition for every row that matches the search index. Referenced columns not\nstored in the search index are fetched from the base table.\n\nConsider the following example: \n\n### GoogleSQL\n\n CREATE TABLE Albums (\n AlbumId STRING(MAX) NOT NULL,\n Title STRING(MAX),\n Rating FLOAT64,\n Genres ARRAY\u003cSTRING(MAX)\u003e,\n Likes INT64,\n Cover BYTES(MAX),\n Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,\n Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN,\n Genres_Tokens TOKENLIST AS (TOKEN(Genres)) HIDDEN\n ) PRIMARY KEY(AlbumId);\n\n CREATE SEARCH INDEX AlbumsIndex\n ON Albums(Title_Tokens, Rating_Tokens, Genres_Tokens)\n STORING (Likes);\n\n### PostgreSQL\n\nSpanner PostgreSQL support has the following\nlimitations:\n\n- `spanner.tokenize_number` function only supports the `bigint` type.\n- `spanner.token` doesn't support tokenizing arrays.\n\n CREATE TABLE albums (\n albumid character varying NOT NULL,\n title character varying,\n rating bigint,\n genres character varying NOT NULL,\n likes bigint,\n cover bytea,\n title_tokens spanner.tokenlist AS (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,\n rating_tokens spanner.tokenlist AS (spanner.tokenize_number(rating)) VIRTUAL HIDDEN,\n genres_tokens spanner.tokenlist AS (spanner.token(genres)) VIRTUAL HIDDEN,\n PRIMARY KEY(albumid));\n\n CREATE SEARCH INDEX albumsindex\n ON albums(title_tokens, rating_tokens, genres_tokens)\n INCLUDE (likes);\n\nThe behavior of queries on this table include the following:\n\n- `Rating` and `Genres` are included in the search index.\n Spanner accelerates conditions using search index posting\n lists. `ARRAY_INCLUDES_ANY`, `ARRAY_INCLUDES_ALL` are GoogleSQL\n functions and are not supported for PostgreSQL dialect.\n\n SELECT Album\n FROM Albums\n WHERE Rating \u003e 4\n AND ARRAY_INCLUDES_ANY(Genres, ['jazz'])\n\n- The query can combine conjunctions, disjunctions, and negations in any way,\n including mixing full-text and non-text predicates. This query is fully\n accelerated by the search index.\n\n SELECT Album\n FROM Albums\n WHERE (SEARCH(Title_Tokens, 'car')\n OR Rating \u003e 4)\n AND NOT ARRAY_INCLUDES_ANY(Genres, ['jazz'])\n\n- `Likes` is stored in the index, but the schema doesn't request\n Spanner to build a token index for its possible values.\n Therefore, the full-text predicate on `Title` and non-text predicate on\n `Rating` is accelerated, but the predicate on `Likes` isn't. In\n Spanner, the query fetches all documents with the term \"car\"\n in the `Title` and a rating more than 4, then it filters documents that\n don't have at least 1000 likes. This query uses a lot of resources if almost\n all albums have the term \"car\" in their title and almost all of them have a\n rating of 5, but few albums have 1000 likes. In such cases, indexing\n `Likes` similarly to `Rating` saves resources.\n\n ### GoogleSQL\n\n SELECT Album\n FROM Albums\n WHERE SEARCH(Title_Tokens, 'car')\n AND Rating \u003e 4\n AND Likes \u003e= 1000\n\n ### PostgreSQL\n\n SELECT album\n FROM albums\n WHERE spanner.search(title_tokens, 'car')\n AND rating \u003e 4\n AND likes \u003e= 1000\n\n- `Cover` isn't stored in the index. The following query does a\n [back join](/spanner/docs/query-execution-plans#index_and_back_join_queries)\n between `AlbumsIndex` and `Albums` to fetch `Cover` for all matching albums.\n\n ### GoogleSQL\n\n SELECT AlbumId, Cover\n FROM Albums\n WHERE SEARCH(Title_Tokens, 'car')\n AND Rating \u003e 4\n\n ### PostgreSQL\n\n SELECT albumid, cover\n FROM albums\n WHERE spanner.search(title_tokens, 'car')\n AND rating \u003e 4\n\nWhat's next\n-----------\n\n- Learn about [full-text search queries](/spanner/docs/full-text-search/query-overview).\n- Learn how to [rank search results](/spanner/docs/full-text-search/ranked-search).\n- Learn how to [perform a substring search](/spanner/docs/full-text-search/substring-search).\n- Learn how to [paginate search results](/spanner/docs/full-text-search/paginate-search-results).\n- Learn how to [search multiple columns](/spanner/docs/full-text-search/search-multiple-columns)."]]