Melakukan penelusuran menggunakan faset

Halaman ini menjelaskan cara menggunakan aspek untuk penelusuran teks lengkap. Sebagai bagian dari pemfilteran interaktif, aspek adalah nilai filter potensial, dan jumlah kecocokan untuk filter tersebut. Di situs yang memiliki kemampuan ini, saat Anda memasukkan frasa penelusuran, Anda akan mendapatkan daftar hasil di menu navigasi, dan ada daftar aspek yang dapat Anda gunakan untuk mempersempit hasil penelusuran, beserta jumlah hasil yang sesuai dengan setiap kategori.

Misalnya, jika Anda menggunakan kueri "foo" untuk menelusuri album, Anda mungkin mendapatkan ratusan hasil. Jika ada aspek genre, Anda dapat memilih berdasarkan genre seperti "rock (250)", "r&b (50)", atau "pop (150)".

Dalam penelusuran teks lengkap Spanner, Anda dapat menggunakan ekspresi SQL standar dan fungsi penelusuran teks lengkap untuk pemfilteran dan penghitungan yang difilter. Anda tidak perlu menggunakan sintaks khusus untuk menggunakan aspek.

Menambahkan faset untuk digunakan dalam penelusuran teks lengkap

Contoh berikut membuat tabel untuk album dan melakukan tokenisasi judul untuk setiap album. Tabel ini digunakan untuk contoh di halaman ini.

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));

Buat indeks penelusuran di Title_Tokens. Jika perlu, Anda dapat menyimpan Title, Genres, dan Rating dalam indeks penelusuran untuk menghindari backjoin ke tabel dasar saat menghitung aspek.

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

Untuk contoh ini, masukkan data berikut ke dalam tabel.

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)

Mengambil nilai jumlah untuk satu faset

Contoh ini menunjukkan cara melakukan penghitungan faset pada faset Rating. Kueri ini melakukan penelusuran teks untuk "foo" dalam kolom Title_Tokens pada tabel Album.

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            |

Mengambil nilai jumlah untuk beberapa faset

Contoh ini menunjukkan langkah-langkah untuk melakukan penghitungan faset pada beberapa faset. Metode ini melakukan hal berikut:

  1. Mengambil hasil penelusuran awal: melakukan penelusuran teks untuk "foo" dalam kolom Title_Tokens pada tabel Albums.
  2. Menghitung jumlah aspek: lalu menghitung jumlah untuk aspek Rating dan 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

Secara khusus, contoh ini melakukan hal berikut:

  • WITH search_results AS (...) mengumpulkan kumpulan besar hasil penelusuran awal untuk digunakan pada halaman pertama hasil dan perhitungan faset.
  • SEARCH(Title_Tokens, "foo") adalah kueri penelusuran utama.
  • LIMIT 10000 membatasi biaya penelusuran dengan mengurangi set hasil menjadi 10.000. Untuk penelusuran yang sangat luas yang dapat menampilkan jutaan hasil, penghitungan jumlah faset yang tepat pada seluruh set data dapat menjadi mahal. Dengan membatasi hasil penelusuran, kueri dapat dengan cepat memberikan perkiraan jumlah aspek (batas bawah). Artinya, jumlah tersebut mencerminkan setidaknya jumlah hasil tersebut,tetapi mungkin ada lebih banyak hasil yang cocok di luar batas 10.000.
  • Subkueri result_page menghasilkan halaman pertama hasil penelusuran yang ditampilkan kepada pengguna. Kueri ini hanya memilih 50 kumpulan data teratas dari search_results, yang diurutkan berdasarkan Likes dan AlbumId. Inilah yang dilihat pengguna pada awalnya.
  • Subkueri rating_counts menghitung jumlah aspek untuk Rating. Fungsi ini mengelompokkan semua data dalam search_results menurut Rating dan menghitung jumlah hasil yang termasuk dalam setiap kategori rating.
  • Subkueri genres_counts menghitung jumlah aspek untuk Genres. Karena berupa array, gabungkan dengan UNNEST(Genres) untuk memperlakukan setiap genre dalam array sebagai baris terpisah untuk penghitungan.

Mengambil halaman berikutnya

Saat membuat kueri untuk halaman berikutnya setelah kueri faset awal, Anda dapat menggunakan kembali jumlah faset yang ditampilkan dari halaman pertama.

Untuk mengetahui informasi selengkapnya tentang cara melakukan penomoran halaman, lihat Menggunakan penomoran halaman berbasis kunci.