dukcapil/migrations/000036_add_search_indexes.up.sql
2025-09-21 20:13:12 +07:00

63 lines
4.5 KiB
PL/PgSQL

-- Add indexes for optimized search on outgoing letters
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_letter_number_text ON letters_outgoing USING gin(to_tsvector('simple', letter_number));
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_subject_text ON letters_outgoing USING gin(to_tsvector('simple', subject));
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_description_text ON letters_outgoing USING gin(to_tsvector('simple', COALESCE(description, '')));
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_reference_number_text ON letters_outgoing USING gin(to_tsvector('simple', COALESCE(reference_number, '')));
-- Composite indexes for common query patterns on outgoing letters
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_status_created ON letters_outgoing(status, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_priority_created ON letters_outgoing(priority_id, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_institution_created ON letters_outgoing(receiver_institution_id, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_created_by ON letters_outgoing(created_by, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_issue_date ON letters_outgoing(issue_date DESC) WHERE deleted_at IS NULL;
-- Add indexes for optimized search on incoming letters
CREATE INDEX IF NOT EXISTS idx_letters_incoming_letter_number_text ON letters_incoming USING gin(to_tsvector('simple', letter_number));
CREATE INDEX IF NOT EXISTS idx_letters_incoming_subject_text ON letters_incoming USING gin(to_tsvector('simple', subject));
CREATE INDEX IF NOT EXISTS idx_letters_incoming_description_text ON letters_incoming USING gin(to_tsvector('simple', COALESCE(description, '')));
CREATE INDEX IF NOT EXISTS idx_letters_incoming_reference_number_text ON letters_incoming USING gin(to_tsvector('simple', COALESCE(reference_number, '')));
-- Composite indexes for common query patterns on incoming letters
CREATE INDEX IF NOT EXISTS idx_letters_incoming_status_created ON letters_incoming(status, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_incoming_priority_created ON letters_incoming(priority_id, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_incoming_institution_created ON letters_incoming(sender_institution_id, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_incoming_created_by ON letters_incoming(created_by, created_at DESC) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_letters_incoming_received_date ON letters_incoming(received_date DESC) WHERE deleted_at IS NULL;
-- Indexes for recipient lookups
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_recipients_user ON letter_outgoing_recipients(user_id, letter_id);
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_recipients_dept ON letter_outgoing_recipients(department_id, letter_id);
CREATE INDEX IF NOT EXISTS idx_letter_incoming_recipients_user ON letter_incoming_recipients(recipient_user_id, letter_id);
CREATE INDEX IF NOT EXISTS idx_letter_incoming_recipients_dept ON letter_incoming_recipients(recipient_department_id, letter_id);
-- Create a function for full-text search on outgoing letters
CREATE OR REPLACE FUNCTION search_outgoing_letters(search_query text)
RETURNS SETOF letters_outgoing AS $$
BEGIN
RETURN QUERY
SELECT * FROM letters_outgoing
WHERE deleted_at IS NULL
AND (
to_tsvector('simple', letter_number) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', subject) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', COALESCE(description, '')) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', COALESCE(reference_number, '')) @@ plainto_tsquery('simple', search_query)
);
END;
$$ LANGUAGE plpgsql;
-- Create a function for full-text search on incoming letters
CREATE OR REPLACE FUNCTION search_incoming_letters(search_query text)
RETURNS SETOF letters_incoming AS $$
BEGIN
RETURN QUERY
SELECT * FROM letters_incoming
WHERE deleted_at IS NULL
AND (
to_tsvector('simple', letter_number) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', subject) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', COALESCE(description, '')) @@ plainto_tsquery('simple', search_query)
OR to_tsvector('simple', COALESCE(reference_number, '')) @@ plainto_tsquery('simple', search_query)
);
END;
$$ LANGUAGE plpgsql;