本頁面說明如何使用 facets 進行全文搜尋。在互動式篩選功能中,分面是潛在的篩選值,以及該篩選條件的相符項目數量。在具備這項功能的網站上輸入搜尋詞組時,導覽選單會顯示結果清單,以及可用於縮小搜尋結果範圍的側欄清單,並顯示符合各類別的結果數量。
舉例來說,如果您使用查詢「foo」搜尋專輯,可能會得到數百個結果。如果類型有分類,你可以依類型選取,例如「搖滾 (250)」、「R&B (50)」或「流行 (150)」。
在 Spanner 全文搜尋中,您可以使用標準 SQL 運算式和全文搜尋函式進行篩選和篩選計數。使用構面時,不需要使用特殊語法。
新增用於全文搜尋的 Facet
下列範例會建立專輯資料表,並為每張專輯的名稱進行權杖化。本頁的範例會使用這個資料表。
GoogleSQL
CREATE TABLE Albums (
AlbumId INT64 NOT NULL,
Title STRING(MAX),
Rating INT64,
Genres ARRAY<STRING(MAX)>,
Likes INT64 NOT NULL,
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
) PRIMARY KEY(AlbumId);
PostgreSQL
CREATE TABLE albums (
albumid bigint NOT NULL,
title text,
rating bigint,
genres text[],
likes bigint NOT NULL,
title_tokens spanner.TOKENLIST GENERATED ALWAYS AS (spanner.TOKENIZE_FULLTEXT(Title)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
在 Title_Tokens
上建立搜尋索引。您可以選擇在搜尋索引中儲存 Title
、Genres
和 Rating
,避免在計算 facets 時回溯加入基本資料表。
GoogleSQL
CREATE SEARCH INDEX AlbumsIndex
ON Albums (Title_Tokens)
STORING (Title, Genres, Rating)
ORDER BY Likes DESC;
PostgreSQL
CREATE SEARCH INDEX albumsindex
ON albums (title_tokens)
INCLUDE (title, genres, rating)
ORDER BY likes DESC
在本範例中,請將下列資料插入資料表。
GoogleSQL
INSERT INTO Albums (AlbumId, Title, Rating, Genres, Likes) VALUES
(1, "The Foo Strike Again", 5, ["Rock", "Alternative"], 600),
(2, "Who are the Who?", 5, ["Progressive", "Indie"], 200),
(3, "No Foo For You", 4, ["Metal", "Alternative"], 50)
PostgreSQL
INSERT INTO albums (albumid, title, rating, genres, likes) VALUES
(1, 'The Foo Strike Again', 5,'{"Rock", "Alternative"}', 600),
(2, 'Who are the Who?', 5,'{"Progressive", "Indie"}', 200),
(3, 'No Foo For You', 4,'{"Metal", "Alternative"}', 50)
擷取單一 facet 的計數值
這個範例說明如何對「評分」面向執行面向計數。這會在 Albums 資料表的 Title_Tokens 欄中執行「foo」的文字搜尋。
GoogleSQL
SELECT Rating, COUNT(*) AS result_count
FROM Albums
WHERE SEARCH(Title_Tokens, "foo")
GROUP BY Rating
ORDER BY Rating DESC
| Rating | result_count |
|--------|--------------|
| 5 | 1 |
| 4 | 1 |
PostgreSQL
SELECT rating, COUNT(*) AS result_count
FROM albums
WHERE spanner.SEARCH(title_tokens, 'foo')
GROUP BY rating
ORDER BY rating DESC;
| rating | result_count |
|--------|--------------|
| 5 | 1 |
| 4 | 1 |
擷取多個商情項目的計數值
這個範例說明如何對多個層面執行層面計數。 這項功能會執行下列操作:
- 擷取初始搜尋結果:在
Albums
表格的Title_Tokens
欄中執行「foo」的文字搜尋。 - 計算側滑片計數:然後計算
Rating
和Genres
側滑片的計數。
GoogleSQL
WITH search_results AS (
SELECT AlbumId, Title, Genres, Rating, Likes
FROM Albums
WHERE SEARCH(Title_Tokens, "foo")
ORDER BY Likes DESC, AlbumId
LIMIT 10000
)
SELECT
-- Result set #1: First page of search results
ARRAY(
SELECT AS STRUCT *
FROM search_results
ORDER BY Likes DESC, AlbumId
LIMIT 50
) as result_page,
-- Result set #2: Number of results by rating
ARRAY(
SELECT AS STRUCT Rating, COUNT(*) as result_count
FROM search_results
GROUP BY Rating
ORDER BY result_count DESC, Rating DESC
) as rating_counts,
-- Result set #3: Number of results for top 5 genres
ARRAY(
SELECT AS STRUCT genre, COUNT(*) as result_count
FROM search_results
JOIN UNNEST(Genres) genre
GROUP BY genre
ORDER BY result_count DESC, genre
LIMIT 5
) as genres_counts
PostgreSQL
WITH search_results AS (
SELECT albumid, title, genres, rating, likes
FROM albums
WHERE spanner.SEARCH(title_tokens, 'foo')
ORDER BY likes DESC, albumid
LIMIT 10000
)
-- The pattern ARRAY(SELECT TO_JSONB ...) enables returning multiple nested
-- result sets in the same query.
SELECT
-- Result set #1: First page of search results
ARRAY(
SELECT JSONB_BUILD_OBJECT(
'albumid', albumid,
'title', title,
'genres', genres,
'rating', rating,
'likes', likes
)
FROM search_results
ORDER BY likes DESC, albumid
LIMIT 50
) as result_page,
-- Result set #2: Number of results by rating
ARRAY(
SELECT JSONB_BUILD_OBJECT(
'rating', rating,
'result_count', COUNT(*)
)
FROM search_results
GROUP BY rating
ORDER BY COUNT(*) DESC, rating DESC
) as rating_counts,
-- Result set #3: Number of results for top 5 genres
ARRAY(
SELECT JSONB_BUILD_OBJECT(
'genre', genre,
'result_count', COUNT(*)
)
FROM
search_results,
UNNEST(genres) AS genre
GROUP BY genre
ORDER BY COUNT(*) DESC, genre
LIMIT 5
) as genres_counts
具體來說,這個範例會執行下列作業:
WITH search_results AS (...)
會收集大量初始搜尋結果,用於第一頁結果和 Facet 計算。SEARCH(Title_Tokens, "foo")
是主要搜尋查詢。LIMIT 10000
會將結果集縮減至 10,000 個,藉此限制搜尋費用。如果搜尋範圍很廣,可能會傳回數百萬筆結果,這時計算整個資料集的確切 Facet 數量可能需要大量資源。藉由限制搜尋結果,查詢可以快速提供近似 (下限) 構面計數。也就是說,計數反映的結果至少有這麼多,但可能還有更多相符結果,只是超過 10,000 筆的上限。result_page
子查詢會產生顯示給使用者的搜尋結果第一頁。這項查詢只會選取前 50 筆記錄 (依Likes
和AlbumId
排序)。search_results
這是使用者一開始看到的畫面。rating_counts
子查詢會計算Rating
的側邊欄篩選條件計數。這項函式會依據Rating
將search_results
中的所有記錄分組,並計算每個評分類別的結果數量。genres_counts
子查詢會計算Genres
的側邊數。由於這是陣列,請使用UNNEST(Genres)
聯結,將陣列中的每個類型視為獨立資料列進行計數。
擷取後續網頁
在初始商情項目查詢後查詢後續頁面時,可以重複使用第一頁傳回的商情項目計數。
如要進一步瞭解如何分頁,請參閱「使用以鍵為準的分頁」。