-- ============================================================ -- Norda Biznes Partner - Improved Search Schema Migration -- ============================================================ -- -- Rozszerzenie wyszukiwania o: -- 1. pg_trgm dla fuzzy matching (literówki) -- 2. Rozszerzony search_vector o usługi i kompetencje -- 3. Indeks trigram dla podobieństwa nazw -- -- Data: 2025-11-26 -- ============================================================ -- 1. Włącz rozszerzenie pg_trgm (fuzzy matching) CREATE EXTENSION IF NOT EXISTS pg_trgm; -- 2. Dodaj indeks trigram na nazwę firmy (dla fuzzy matching) CREATE INDEX IF NOT EXISTS idx_companies_name_trgm ON companies USING gin(name gin_trgm_ops); -- 3. Dodaj indeks trigram na opis krótki CREATE INDEX IF NOT EXISTS idx_companies_desc_trgm ON companies USING gin(description_short gin_trgm_ops); -- 4. Rozszerzona funkcja search trigger (uwzględnia usługi i kompetencje) CREATE OR REPLACE FUNCTION companies_search_trigger_full() RETURNS trigger AS $$ DECLARE services_text TEXT; competencies_text TEXT; BEGIN -- Pobierz nazwy usług przypisanych do firmy SELECT string_agg(s.name, ' ') INTO services_text FROM company_services cs JOIN services s ON s.id = cs.service_id WHERE cs.company_id = NEW.id; -- Pobierz nazwy kompetencji przypisanych do firmy SELECT string_agg(c.name, ' ') INTO competencies_text FROM company_competencies cc JOIN competencies c ON c.id = cc.competency_id WHERE cc.company_id = NEW.id; -- Buduj rozszerzony wektor wyszukiwania NEW.search_vector := setweight(to_tsvector('simple', COALESCE(NEW.name, '')), 'A') || setweight(to_tsvector('simple', COALESCE(NEW.description_short, '')), 'B') || setweight(to_tsvector('simple', COALESCE(NEW.description_full, '')), 'C') || setweight(to_tsvector('simple', COALESCE(services_text, '')), 'B') || setweight(to_tsvector('simple', COALESCE(competencies_text, '')), 'B') || setweight(to_tsvector('simple', COALESCE(NEW.address_city, '')), 'D'); RETURN NEW; END; $$ LANGUAGE plpgsql; -- 5. Zastąp stary trigger nowym (jeśli istnieje) DROP TRIGGER IF EXISTS tsvector_update ON companies; CREATE TRIGGER tsvector_update BEFORE INSERT OR UPDATE ON companies FOR EACH ROW EXECUTE FUNCTION companies_search_trigger_full(); -- 6. Funkcja do przebudowy search_vector dla istniejących firm CREATE OR REPLACE FUNCTION rebuild_search_vectors() RETURNS void AS $$ DECLARE company_rec RECORD; BEGIN FOR company_rec IN SELECT id FROM companies LOOP -- Trigger zostanie wywołany przez UPDATE UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = company_rec.id; END LOOP; END; $$ LANGUAGE plpgsql; -- 7. Przebuduj search vectory dla wszystkich firm SELECT rebuild_search_vectors(); -- 8. Dodaj trigger na company_services (gdy dodajemy usługę, przebuduj wektor) CREATE OR REPLACE FUNCTION update_company_search_on_service_change() RETURNS trigger AS $$ BEGIN IF TG_OP = 'DELETE' THEN UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = OLD.company_id; RETURN OLD; ELSE UPDATE companies SET last_updated = CURRENT_TIMESTAMP WHERE id = NEW.company_id; RETURN NEW; END IF; END; $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS trigger_service_search_update ON company_services; CREATE TRIGGER trigger_service_search_update AFTER INSERT OR UPDATE OR DELETE ON company_services FOR EACH ROW EXECUTE FUNCTION update_company_search_on_service_change(); -- 9. Dodaj trigger na company_competencies DROP TRIGGER IF EXISTS trigger_competency_search_update ON company_competencies; CREATE TRIGGER trigger_competency_search_update AFTER INSERT OR UPDATE OR DELETE ON company_competencies FOR EACH ROW EXECUTE FUNCTION update_company_search_on_service_change(); -- 10. Podsumowanie DO $$ BEGIN RAISE NOTICE '=== Migracja zakończona pomyślnie ==='; RAISE NOTICE 'Dodano: pg_trgm, indeksy trigram, rozszerzony search trigger'; RAISE NOTICE 'Przebudowano search vectors dla wszystkich firm'; END $$;