Skip to content

Instantly share code, notes, and snippets.

@ololobus
Created December 4, 2015 22:58
Show Gist options
  • Save ololobus/ba24ff1c67301744f402 to your computer and use it in GitHub Desktop.
Save ololobus/ba24ff1c67301744f402 to your computer and use it in GitHub Desktop.
PostgreSQL create index and full-text search query
UPDATE tus SET text1_tsvector = to_tsvector(COALESCE(lang1_psql, 'simple')::regconfig, COALESCE(text1, ''));
UPDATE tus SET text2_tsvector = to_tsvector(COALESCE(lang2_psql, 'simple')::regconfig, COALESCE(text2, ''));
/* CREATE INDEX text1_tsvector_idx ON tus USING gin(text1_tsvector);
CREATE INDEX text2_tsvector_idx ON tus USING gin(text2_tsvector); */
CREATE INDEX text_tsvector_idx ON tus USING gin(text1_tsvector, text2_tsvector);
CREATE FUNCTION text_tsvector_update() RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.text1_tsvector = to_tsvector(COALESCE(NEW.lang1_psql, 'simple')::regconfig, COALESCE(NEW.text1, ''));
NEW.text2_tsvector = to_tsvector(COALESCE(NEW.lang2_psql, 'simple')::regconfig, COALESCE(NEW.text2, ''));
END IF;
IF TG_OP = 'UPDATE' THEN
IF NEW.text1 <> OLD.text1 THEN
NEW.text1_tsvector = to_tsvector(COALESCE(NEW.lang1_psql, 'simple')::regconfig, COALESCE(NEW.text1, ''));
END IF;
IF NEW.text2 <> OLD.text2 THEN
NEW.text2_tsvector = to_tsvector(COALESCE(NEW.lang2_psql, 'simple')::regconfig, COALESCE(NEW.text2, ''));
END IF;
END IF;
RETURN NEW;
END
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON tus
FOR EACH ROW EXECUTE PROCEDURE text_tsvector_update();
WITH cache AS (SELECT plainto_tsquery(COALESCE(:lang1_psql, 'simple')::regconfig, :query) AS tsquery)
SELECT id, lang1, lang2,
CASE lang1
WHEN :lang1 THEN ts_headline(COALESCE(:lang1_psql, 'simple')::regconfig, text1, (SELECT tsquery FROM cache), 'StartSel = <***, StopSel = ***>')
WHEN :lang2 THEN text1
END AS text1,
CASE lang1
WHEN :lang1 THEN text2
WHEN :lang2 THEN ts_headline(COALESCE(:lang1_psql, 'simple')::regconfig, text2, (SELECT tsquery FROM cache), 'StartSel = <***, StopSel = ***>')
END AS text2,
topic, tm_id
FROM (
SELECT "tus".id, lang1, lang2, text1, text2, topic, tm_id,
CASE "tus".lang1
WHEN :lang1 THEN ts_rank_cd(text1_tsvector, (SELECT tsquery FROM cache))
WHEN :lang2 THEN ts_rank_cd(text2_tsvector, (SELECT tsquery FROM cache))
END AS rank
FROM "tus"
WHERE ("tus".lang1 = :lang1 AND "tus".lang2 = :lang2 AND text1_tsvector @@ (SELECT tsquery FROM cache) AND length(text1) < length(:query) + :add_length)
OR ("tus".lang1 = :lang2 AND "tus".lang2 = :lang1 AND text2_tsvector @@ (SELECT tsquery FROM cache) AND length(text2) < length(:query) + :add_length)
ORDER BY rank DESC
LIMIT :limit OFFSET :offset
) AS foo;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment