Menentukan peringkat hasil penelusuran

Halaman ini menjelaskan cara menentukan peringkat hasil penelusuran untuk penelusuran teks lengkap di Spanner.

Spanner mendukung penghitungan skor topik, yang menyediakan blok penyusun untuk membuat fungsi peringkat yang canggih. Skor ini menghitung relevansi hasil dengan kueri, berdasarkan frekuensi istilah kueri dan opsi lain yang dapat disesuaikan.

Contoh berikut menunjukkan cara melakukan penelusuran berperingkat menggunakan SCORE fungsi:

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC

PostgreSQL

Contoh ini menggunakan spanner.search dengan spanner.score.

SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC

Memberi skor pada istilah kueri dengan fungsi SCORE

Fungsi SCORE menghitung skor untuk setiap istilah kueri, lalu menggabungkan skor tersebut. Skor per istilah kira-kira didasarkan pada frekuensi istilah–frekuensi dokumen terbalik (TF/IDF). Skor adalah salah satu komponen dari pengurutan akhir untuk sebuah rekaman. Kueri menggabungkannya dengan sinyal lain, seperti kesegaran yang memodulasi skor topik.

Dalam penerapan saat ini, bagian IDF dari TF/IDF hanya tersedia saat enhance_query=>true digunakan. Bagian ini menghitung frekuensi relatif kata berdasarkan korpus web lengkap yang digunakan oleh Google Penelusuran, bukan indeks penelusuran tertentu. Jika peningkatan rquery tidak diaktifkan, pemberian skor hanya menggunakan komponen frekuensi istilah (TF) (yaitu, istilah IDF ditetapkan ke 1).

Fungsi SCORE menampilkan nilai yang berfungsi sebagai skor relevansi yang digunakan Spanner untuk menetapkan urutan pengurutan. Nilai tersebut tidak memiliki arti yang berdiri sendiri. Semakin tinggi skornya, semakin baik kecocokannya dengan kueri.

Biasanya argumen seperti query dan enhance_query sama di seluruh SEARCH dan SCORE fungsi untuk memastikan konsistensi dalam pengambilan dan peringkat.

Cara yang direkomendasikan untuk melakukannya adalah menggunakan argumen ini dengan parameter kueri bukan literal string, dan menentukan parameter kueri yang sama dalam fungsi SEARCH dan SCORE.

Memberi skor pada beberapa kolom

Spanner menggunakan fungsi SCORE untuk memberi skor pada setiap kolom secara individual. Kueri kemudian menggabungkan skor individual ini. Cara umum untuk melakukannya adalah dengan menjumlahkan skor individual, lalu meningkatkan skor tersebut sesuai dengan bobot kolom yang diberikan pengguna (yang diberikan menggunakan parameter kueri SQL).

Misalnya, kueri berikut menggabungkan output dari dua fungsi SCORE:

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight
LIMIT 25

PostgreSQL

Contoh ini menggunakan parameter kueri $1 dan $2 yang masing-masing terikat ke 'fifth symphony' dan 'blue note'.

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
ORDER BY spanner.score(title_tokens, $1) * $titleweight
        + spanner.score(studio_tokens, $2) * $studioweight
LIMIT 25

Contoh berikut menambahkan dua parameter peningkatan:

  • Kesegaran (FreshnessBoost) meningkatkan skor dengan (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30)
  • Popularitas(PopularityBoost) meningkatkan skor dengan mengalikannya dengan faktor (1 + IF(HasGrammy, @grammyweight, 0).

Agar mudah dibaca, kueri menggunakan operator WITH.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY WITH(
  TitleScore AS SCORE(Title_Tokens, @p1) * @titleweight,
  StudioScore AS SCORE(Studio_Tokens, @p2) * @studioweight,
  DaysOld AS (UNIX_MICROS(CURRENT_TIMESTAMP()) - ReleaseTimestamp) / 8.64e+10,
  FreshnessBoost AS (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30),
  PopularityBoost AS (1 + IF(HasGrammy, @grammyweight, 0)),
  (TitleScore + StudioScore) * FreshnessBoost * PopularityBoost)
LIMIT 25

PostgreSQL

Contoh ini menggunakan parameter kueri $1, $2, $3, $4, $5, dan $6 yang masing-masing terikat ke nilai yang ditentukan untuk titlequery, studioquery, titleweight, studioweight, grammyweight, dan freshnessweight.

SELECT albumid
FROM
  (
    SELECT
      albumid,
      spanner.score(title_tokens, $1) * $3 AS titlescore,
      spanner.score(studio_tokens, $2) * $4 AS studioscore,
      (extract(epoch FROM current_timestamp) * 10e+6 - releasetimestamp) / 8.64e+10 AS daysold,
      (1 + CASE WHEN hasgrammy THEN $5 ELSE 0 END) AS popularityboost
    FROM albums
    WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
  ) AS subquery
ORDER BY (subquery.TitleScore + subquery.studioscore)
  * (1 + $6 * greatest(0, 30 - subquery.daysold) / 30) * subquery.popularityboost
LIMIT 25

TOKENLIST_CONCAT juga dapat digunakan dalam penelusuran dan pemberian skor untuk menyederhanakan kueri jika sesuai.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
ORDER BY SCORE(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
LIMIT 25

PostgreSQL

Contoh ini menggunakan spanner.tokenlist_concat. Parameter kueri $1 terikat ke 'blue note'.

SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
ORDER BY spanner.score(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
LIMIT 25

Meningkatkan kecocokan urutan kueri

Spanner menerapkan peningkatan perkalian ke output fungsi SCORE untuk nilai yang berisi istilah kueri dalam urutan yang sama dengan yang muncul dalam kueri. Ada dua versi peningkatan ini: kecocokan parsial dan kecocokan persis. Peningkatan kecocokan parsial diterapkan saat:

  1. TOKENLIST berisi semua istilah asli dalam kueri.
  2. Token berdekatan satu sama lain, dan dalam urutan yang sama dengan yang muncul dalam kueri.

Ada aturan khusus tertentu untuk konjungsi, negasi, dan frasa:

  • Kueri dengan negasi tidak dapat menerima peningkatan kecocokan parsial.
  • Kueri dengan konjungsi menerima peningkatan jika bagian dari konjungsi muncul di lokasi yang sesuai.
  • Kueri dengan frasa menerima peningkatan jika frasa muncul di TOKENLIST, dan istilah di sebelah kiri frasa dalam kueri muncul di sebelah kiri frasa di TOKENLIST, dan hal yang sama berlaku untuk istilah di sebelah kanan frasa.

Spanner menerapkan peningkatan kecocokan persis jika semua aturan sebelumnya benar, dan token pertama dan terakhir dalam kueri adalah token pertama dan terakhir dalam dokumen.

Contoh dokumen: Bridge Over Troubled Water

Kueri Peningkatan Diterapkan
Bridge Troubled tidak ada peningkatan
Bridge Over - other water tidak ada peningkatan
Bridge (Over OR Troubled) Water tidak ada peningkatan
Bridge Over peningkatan parsial
Bridge Over (Troubled OR Water) peningkatan parsial
Bridge Over Troubled Water peningkatan persis
Bridge "Over Troubled" Water peningkatan persis
Bridge ("Over Troubled" OR missingterm) Water peningkatan persis

Versi pemberi skor

Algoritma pemberi skor diperbarui secara berkala. Setiap rilis menggabungkan serangkaian peningkatan algoritma pemberian skor. Untuk mengetahui daftar perbedaan mendetail antarversi, lihat Versi Pemberi Skor.

Anda dapat menetapkan versi pemberi skor default untuk database, atau menentukan versi untuk kueri tertentu.

Menetapkan versi pemberi skor default database

Anda dapat menetapkan versi default algoritma pemberi skor untuk database. Opsi ini menentukan versi algoritma pemberian skor yang digunakan Spanner saat fungsi SCORE dipanggil tanpa opsi skor version eksplisit.

GoogleSQL

Tetapkan opsi database score_version:

ALTER DATABASE database_name SET OPTIONS (score_version = 2)

PostgreSQL

Tetapkan opsi database spanner.score_version:

ALTER DATABASE database_name SET "spanner.score_version" = 2

Nilai yang valid untuk opsi database adalah 1 atau 2. Jika parameter version ada dalam permintaan, parameter tersebut akan mengganti versi default database.

Mengganti versi pemberi skor per kueri

Anda dapat mengganti versi pemberi skor default untuk kueri tertentu menggunakan parameter version dalam argumen options fungsi SCORE. Jika kueri menentukan versi pemberi skor, kueri tersebut akan mengganti versi default database.

Contoh berikut mengganti versi pemberi skor default dengan menentukan version dalam parameter options:

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, @query)
ORDER BY SCORE(
  AlbumTitle_Tokens,
  @query,
  options=>JSON '{"version": 2}'
) DESC

PostgreSQL

Contoh ini menggunakan parameter kueri $1 yang terikat ke string kueri.

SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, $1)
ORDER BY spanner.score(
  albumtitle_tokens,
  $1,
  options => '{"version": 2}'::jsonb
) DESC

Membatasi kedalaman pengambilan

Indeks penelusuran sering kali berisi jutaan dokumen. Untuk kueri yang predikatnya memiliki selektivitas rendah, tidak praktis untuk menentukan peringkat semua hasil. Kueri pemberian skor biasanya memiliki dua batas:

  1. Batas kedalaman pengambilan: jumlah maksimum baris yang akan diberi skor.
  2. Batas ukuran kumpulan hasil: jumlah maksimum baris yang harus ditampilkan kueri (biasanya ukuran halaman).

Kueri dapat membatasi kedalaman pengambilan dengan subkueri SQL:

GoogleSQL

SELECT AlbumId
FROM
  (
    SELECT AlbumId, SCORE(Title_Tokens, @p1) AS score
    FROM Albums
    WHERE SEARCH(Title_Tokens, @p1)
    ORDER BY ReleaseTimestamp DESC
    LIMIT @retrieval_limit
  )
ORDER BY score DESC
LIMIT @page_size

PostgreSQL

Contoh ini menggunakan parameter kueri $1, $2, dan $3 yang masing-masing terikat ke nilai yang ditentukan untuk title_query, retrieval_limit, dan page_size.

SELECT albumid
FROM
  (
    SELECT albumid, spanner.score(title_tokens, $1) AS score
    FROM albums
    WHERE spanner.search(title_tokens, $1)
    ORDER BY releasetimestamp DESC
    LIMIT $2
  ) AS subquery
ORDER BY score DESC
LIMIT $3

Hal ini berfungsi sangat baik jika Spanner menggunakan sinyal penentu peringkat terpenting untuk mengurutkan indeks.

Langkah berikutnya