CREATE EXTENSION IF NOT EXISTS pg_trgm; ALTER TABLE posts ADD COLUMN IF NOT EXISTS search_text TEXT NOT NULL DEFAULT ''; ALTER TABLE pages ADD COLUMN IF NOT EXISTS search_text TEXT NOT NULL DEFAULT ''; CREATE OR REPLACE FUNCTION normalize_public_search_text(value TEXT) RETURNS TEXT LANGUAGE sql IMMUTABLE AS $$ SELECT lower(trim(regexp_replace( regexp_replace( regexp_replace(coalesce(value, ''), E'!\\[[^]]*\\]\\([^)]*\\)', ' ', 'g'), E'/uploads/[^[:space:])"]+', ' ', 'g' ), E'[[:space:]]+', ' ', 'g' ))) $$; CREATE OR REPLACE FUNCTION set_post_search_text() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NEW.search_text := normalize_public_search_text(concat_ws(E'\n', NEW.title, NEW.excerpt, NEW.content)); RETURN NEW; END; $$; CREATE OR REPLACE FUNCTION set_page_search_text() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NEW.search_text := normalize_public_search_text(concat_ws(E'\n', NEW.title, NEW.listing_section, NEW.listing_title, NEW.listing_description, NEW.content)); RETURN NEW; END; $$; DROP TRIGGER IF EXISTS posts_search_text_before_write ON posts; CREATE TRIGGER posts_search_text_before_write BEFORE INSERT OR UPDATE OF title, excerpt, content ON posts FOR EACH ROW EXECUTE FUNCTION set_post_search_text(); DROP TRIGGER IF EXISTS pages_search_text_before_write ON pages; CREATE TRIGGER pages_search_text_before_write BEFORE INSERT OR UPDATE OF title, listing_section, listing_title, listing_description, content ON pages FOR EACH ROW EXECUTE FUNCTION set_page_search_text(); UPDATE posts SET search_text = normalize_public_search_text(concat_ws(E'\n', title, excerpt, content)); UPDATE pages SET search_text = normalize_public_search_text(concat_ws(E'\n', title, listing_section, listing_title, listing_description, content)); CREATE INDEX IF NOT EXISTS posts_public_search_text_trgm_idx ON posts USING gin (search_text gin_trgm_ops) WHERE status = 'published'; CREATE INDEX IF NOT EXISTS pages_public_search_text_trgm_idx ON pages USING gin (search_text gin_trgm_ops) WHERE status = 'published' AND is_listed = true; CREATE INDEX IF NOT EXISTS tags_name_trgm_idx ON tags USING gin ((lower(name)) gin_trgm_ops); CREATE INDEX IF NOT EXISTS tags_slug_trgm_idx ON tags USING gin ((lower(slug)) gin_trgm_ops);