Tetap teratur dengan koleksi
Simpan dan kategorikan konten berdasarkan preferensi Anda.
Halaman ini menjelaskan cara menentukan peringkat hasil penelusuran untuk
penelusuran teks lengkap di
Spanner.
Spanner mendukung komputasi skor keaktualan, yang menyediakan
blok penyusun untuk membuat fungsi peringkat yang canggih. Skor ini
menghitung relevansi hasil terhadap kueri, berdasarkan frekuensi istilah
kueri dan opsi lain yang dapat disesuaikan.
Contoh berikut menunjukkan cara melakukan penelusuran dengan peringkat menggunakan fungsi SCORE:
Fungsi SCORE
menghitung skor untuk setiap istilah kueri, lalu menggabungkan skor tersebut. Skor
per istilah secara kasar didasarkan pada frekuensi istilah–frekuensi dokumen terbalik
(TF/IDF). Skor adalah salah satu
komponen pengurutan akhir untuk data. Kueri menggabungkannya dengan sinyal
lainnya, seperti keaktualan yang memodulasi skor keaktualan.
Dalam implementasi saat ini, bagian IDF dari TF/IDF hanya tersedia jika
enhance_query=>true digunakan. Alat ini menghitung frekuensi relatif kata
berdasarkan korpus web lengkap yang digunakan oleh Google Penelusuran, bukan
indeks penelusuran tertentu. Jika peningkatan rquery tidak diaktifkan, penskoran 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 ini tidak memiliki makna
mandiri. Makin tinggi skornya, makin baik kecocokannya dengan kueri.
Biasanya argumen seperti query dan enhance_query sama di seluruh
fungsi SEARCH dan SCORE 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.
Memberikan skor ke beberapa kolom
Spanner menggunakan fungsi SCORE untuk menilai setiap kolom secara terpisah. Kueri kemudian menggabungkan skor individual ini. Cara umum untuk melakukannya adalah dengan menjumlahkan setiap skor, lalu meningkatkannya sesuai dengan bobot kolom yang diberikan pengguna (yang diberikan menggunakan parameter kueri SQL).
Misalnya, kueri berikut menggabungkan output dari dua fungsi SCORE:
Contoh ini menggunakan parameter kueri $1, $2, $3, $4, $5, dan $6
yang terikat dengan nilai yang ditentukan untuk titlequery, studioquery,
titleweight, studioweight, grammyweight, dan freshnessweight,
masing-masing.
Spanner menerapkan peningkatan multiplikatif ke output
fungsi SCORE untuk nilai yang berisi istilah kueri dalam urutan yang sama dengan
munculnya dalam kueri. Ada dua versi pengoptimalan ini: pencocokan parsial
dan pencocokan persis. Peningkatan pencocokan sebagian diterapkan jika:
TOKENLIST berisi semua istilah asli dalam kueri.
Token berdekatan satu sama lain, dan dalam urutan yang sama seperti yang muncul
dalam kueri.
Ada aturan khusus tertentu untuk konjungsi, negasi, dan frasa:
Kueri dengan negasi tidak dapat menerima peningkatan pencocokan sebagian.
Kueri dengan konjungsi akan menerima peningkatan jika bagian konjungsi
muncul di lokasi yang sesuai.
Kueri dengan frasa akan menerima peningkatan jika frasa muncul di
TOKENLIST, dan istilah di sebelah kiri frasa dalam kueri muncul di
sebelah kiri frasa dalam TOKENLIST, dan hal yang sama berlaku untuk istilah
di sebelah kanan frasa.
Spanner menerapkan peningkatan pencocokan 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
Jembatan Bermasalah
tanpa boost
Jembatan - air lainnya
tanpa boost
Jembatan (Di Atas ATAU Bermasalah) Air
tanpa boost
Bridge Over
peningkatan parsial
Jembatan (Air ATAU Bermasalah)
peningkatan parsial
Bridge Over Troubled Water
peningkatan persis
Jembatan "Di Atas Air yang Bermasalah"
peningkatan persis
Jembatan ("Over Troubled" ATAU missingterm) Air
peningkatan persis
Membatasi kedalaman pengambilan
Indeks penelusuran sering kali berisi jutaan dokumen. Untuk kueri dengan prediket yang memiliki daya pilih rendah, tidak praktis untuk memberi peringkat pada semua hasil.
Kueri penskoran biasanya memiliki dua batas:
Batas kedalaman pengambilan: jumlah maksimum baris yang akan diberi skor.
Batas ukuran set hasil: jumlah maksimum baris yang harus
ditampilkan oleh kueri (biasanya ukuran halaman).
Kueri dapat membatasi kedalaman pengambilan dengan subkueri SQL:
[[["Mudah dipahami","easyToUnderstand","thumb-up"],["Memecahkan masalah saya","solvedMyProblem","thumb-up"],["Lainnya","otherUp","thumb-up"]],[["Sulit dipahami","hardToUnderstand","thumb-down"],["Informasi atau kode contoh salah","incorrectInformationOrSampleCode","thumb-down"],["Informasi/contoh yang saya butuhkan tidak ada","missingTheInformationSamplesINeed","thumb-down"],["Masalah terjemahan","translationIssue","thumb-down"],["Lainnya","otherDown","thumb-down"]],["Terakhir diperbarui pada 2025-08-17 UTC."],[],[],null,["# Rank search results\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 rank search results for\n[full-text searches](/spanner/docs/full-text-search) in\nSpanner.\n\nSpanner supports computing a topicality score, which provides a\nbuilding block for creating sophisticated ranking functions. These scores\ncalculate the relevance of a result to a query, based on the query term\nfrequency and other customizable options.\n\nThe following example shows how to perform a ranked search using the\n[`SCORE`](/spanner/docs/reference/standard-sql/search_functions#score)\nfunction: \n\n### GoogleSQL\n\n SELECT AlbumId\n FROM Albums\n WHERE SEARCH(AlbumTitle_Tokens, \"fifth symphony\")\n ORDER BY SCORE(AlbumTitle_Tokens, \"fifth symphony\") DESC\n\n### PostgreSQL\n\nThis example uses [`spanner.search`](/spanner/docs/reference/postgresql/functions-and-operators#search_functions)\nwith\n[`spanner.score`](/spanner/docs/reference/postgresql/functions-and-operators#search_functions). \n\n SELECT albumid\n FROM albums\n WHERE spanner.search(albumtitle_tokens, 'fifth symphony')\n ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC\n\nScore query terms with the `SCORE` function\n-------------------------------------------\n\nThe [`SCORE`](/spanner/docs/reference/standard-sql/search_functions#score)\nfunction computes a score for each query term and then combines the scores. The\nper-term score is roughly based on [term frequency--inverse document frequency\n(TF/IDF)](https://en.wikipedia.org/wiki/Tf%E2%80%93idf). The score is one\ncomponent of the final ordering for a record. The query combines it with other\nsignals, such as the freshness modulating the topicality score.\n\nIn the current implementation, the IDF part of TF/IDF is only available when\n`enhance_query=\u003etrue` is used. It calculates the relative frequency of words\nbased on the full web corpus used by Google Search, rather than a\nspecific search index. If rquery enhancement isn't enabled, the scoring only\nuses the term frequency (TF) component (that is, the IDF term is set to 1).\n\nThe `SCORE` function returns values that serve as relevance scores that\nSpanner uses to establish a sort order. They have no standalone\nmeaning. The higher the score, the better it matches the query.\n\nUsually arguments like `query` and `enhance_query` are the same across both\n`SEARCH` and `SCORE` functions to ensure consistency in retrieval and ranking.\n\nThe recommended way to do this is to use these arguments with\n[query parameters](/spanner/docs/reference/standard-sql/lexical#query_parameters)\nrather than string literals and specify the same query parameters in the\n`SEARCH` and `SCORE` functions.\n\nScore multiple columns\n----------------------\n\nSpanner uses the `SCORE` function to score each field\nindividually. The query then combines these individual scores together. A common\nway of doing this is to sum up the individual scores and then boost them\naccording to user-provided field weights (which are provided using SQL query\nparameters).\n\nFor example, the following query combines the output of two `SCORE` functions: \n\n### GoogleSQL\n\n SELECT AlbumId\n FROM Albums\n WHERE SEARCH(Title_Tokens, @p1) AND SEARCH(Studio_Tokens, @p2)\n ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight\n LIMIT 25\n\n### PostgreSQL\n\nThis example uses query parameters `$1` and `$2` which are bound to\n'fifth symphony' and 'blue note', respectively. \n\n SELECT albumid\n FROM albums\n WHERE spanner.search(title_tokens, $1) AND spanner.search(studio_tokens, $2)\n ORDER BY spanner.score(title_tokens, $1) * $titleweight\n + spanner.score(studio_tokens, $2) * $studioweight\n LIMIT 25\n\nThe following example adds two boost parameters:\n\n- Freshness (`FreshnessBoost`) increases the score with `(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30)`\n- Popularity(`PopularityBoost`) increases the score by multiplying it by factor `(1 + IF(HasGrammy, @grammyweight, 0)`.\n\nFor readability, the query uses the `WITH` operator. \n\n### GoogleSQL\n\n SELECT AlbumId\n FROM Albums\n WHERE SEARCH(Title_Tokens, @p1) AND SEARCH(Studio_Tokens, @p2)\n ORDER BY WITH(\n TitleScore AS SCORE(Title_Tokens, @p1) * @titleweight,\n StudioScore AS SCORE(Studio_Tokens, @p2) * @studioweight,\n DaysOld AS (UNIX_MICROS(CURRENT_TIMESTAMP()) - ReleaseTimestamp) / 8.64e+10,\n FreshnessBoost AS (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30),\n PopularityBoost AS (1 + IF(HasGrammy, @grammyweight, 0)),\n (TitleScore + StudioScore) * FreshnessBoost * PopularityBoost)\n LIMIT 25\n\n### PostgreSQL\n\nThis example uses query parameters `$1`, `$2`, `$3`, `$4`, `$5`, and `$6`\nwhich are bound to values specified for `titlequery`, `studioquery`,\n`titleweight`, `studioweight`, `grammyweight`, and `freshnessweight`,\nrespectively. \n\n SELECT albumid\n FROM\n (\n SELECT\n albumid,\n spanner.score(title_tokens, $1) * $3 AS titlescore,\n spanner.score(studio_tokens, $2) * $4 AS studioscore,\n (extract(epoch FROM current_timestamp) * 10e+6 - releasetimestamp) / 8.64e+10 AS daysold,\n (1 + CASE WHEN hasgrammy THEN $5 ELSE 0 END) AS popularityboost\n FROM albums\n WHERE spanner.search(title_tokens, $1) AND spanner.search(studio_tokens, $2)\n ) AS subquery\n ORDER BY (subquery.TitleScore + subquery.studioscore)\n * (1 + $6 * greatest(0, 30 - subquery.daysold) / 30) * subquery.popularityboost\n LIMIT 25\n\n[`TOKENLIST_CONCAT`](/spanner/docs/reference/standard-sql/search_functions#tokenlist_concat)\ncan also used in both searching and scoring to simplify queries when\nappropriate. \n\n### GoogleSQL\n\n SELECT AlbumId\n FROM Albums\n WHERE SEARCH(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)\n ORDER BY SCORE(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)\n LIMIT 25\n\n### PostgreSQL\n\nThis example uses\n[`spanner.tokenlist_concat`](/spanner/docs/reference/postgresql/functions-and-operators#search_functions).\nThe query parameter `$1` is bound to 'blue note'. \n\n SELECT albumid\n FROM albums\n WHERE spanner.search(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)\n ORDER BY spanner.score(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)\n LIMIT 25\n\nBoost query order matches\n-------------------------\n\nSpanner applies a multiplicative boost to the output of the\n`SCORE` function for values that contain the query terms in the same order that\nthey appear in the query. There are two versions of this boost: partial match\nand exact match. A partial match boost is applied when:\n\n1. The `TOKENLIST` contains all the original terms in the query.\n2. The tokens are adjacent to one another, and in the same order as they appear in the query.\n\nThere are certain special rules for conjunctions, negations, and phrases:\n\n- A query with a negation can't receive a partial match boost.\n- A query with a conjunction receives a boost if part of the conjunction appears in the appropriate locations.\n- A query with a phrase receives a boost if the phrase appears in the `TOKENLIST`, and the term to the left of the phrase in the query appears to the left of the phrase in the `TOKENLIST`, and the same applies to the term to the right of the phrase.\n\nSpanner applies an exact match boost when all of the previous\nrules are true, and the first and last tokens in the query are the first and\nlast tokens in the document.\n\n**Example document: Bridge Over Troubled Water**\n\nLimit retrieval depth\n---------------------\n\nSearch indexes often contain millions of documents. For queries where the\npredicates have low selectivity, it's impractical to rank all the results.\nScoring queries usually have two limits:\n\n1. **Retrieval depth limit**: the maximum number of rows to score.\n2. **Result set size limit**: the maximum number of rows that the query should return (typically the page size).\n\nQueries can limit retrieval depth with SQL subqueries: \n\n### GoogleSQL\n\n SELECT *\n FROM (\n SELECT AlbumId, Title_Tokens\n FROM Albums\n WHERE SEARCH(Title_Tokens, @p1)\n ORDER BY ReleaseTimestamp DESC\n LIMIT @retrieval_limit\n )\n ORDER BY SCORE(Title_Tokens, @p1)\n LIMIT @page_size\n\n### PostgreSQL\n\nThis example uses query parameters `$1`, `$2`, and `$3` which are bound to\nvalues specified for `title_query`, `retrieval_limit`, and `page_size`,\nrespectively. \n\n SELECT *\n FROM (\n SELECT albumid, title_tokens\n FROM albums\n WHERE spanner.search(title_tokens, $1)\n ORDER BY releasetimestamp DESC\n LIMIT $2\n ) AS subquery\n ORDER BY spanner.score(subquery.title_tokens, $1)\n LIMIT $3\n\nThis works particularly well if Spanner uses the most important\nranking signal to sort the index.\n\nWhat's next\n-----------\n\n- Learn about [full-text search queries](/spanner/docs/full-text-search/query-overview).\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 [mix full-text and non-text queries](/spanner/docs/full-text-search/mix-full-text-and-non-text-queries).\n- Learn how to [search multiple columns](/spanner/docs/full-text-search/search-multiple-columns)."]]