26 lines
1.4 KiB
SQL
26 lines
1.4 KiB
SQL
-- Lexical search over video titles.
|
|
--
|
|
-- The vector is a generated column rather than something the consumer writes:
|
|
-- the catalogue's only writer is SaveVideo, and a title that arrives in an
|
|
-- announcement should be searchable because it is stored, not because a second
|
|
-- statement remembered to index it. STORED because a GIN index needs the value
|
|
-- on disk to index it at all.
|
|
--
|
|
-- 'arabic' is the text search configuration, not 'english' or 'simple': it
|
|
-- stems Arabic (الوثائقي -> وثايق) while leaving Latin-script tokens as written,
|
|
-- which is the right trade for a mixed catalogue. The cost is that English
|
|
-- words are not stemmed, so "documentaries" does not find "documentary".
|
|
--
|
|
-- The configuration is named explicitly rather than left to default_text_search_config,
|
|
-- which is a per-session GUC — an expression that reads it is only STABLE, and
|
|
-- a generated column requires IMMUTABLE. Naming it is also what keeps the
|
|
-- column and every query in step: a query built with a different
|
|
-- configuration would stem its terms differently and silently match nothing.
|
|
ALTER TABLE videos
|
|
ADD COLUMN search_vector tsvector
|
|
GENERATED ALWAYS AS (to_tsvector('arabic', title)) STORED;
|
|
|
|
-- GIN, not GiST: the catalogue is read far more than it is written, and GIN
|
|
-- answers @@ faster at the cost of a slower update — the right way round here.
|
|
CREATE INDEX videos_search_vector_idx ON videos USING GIN (search_vector);
|