Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/api-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
- main
paths:
- 'api/**'
- 'db/**'
Comment thread
RobinGummels marked this conversation as resolved.
- '.github/workflows/api-ci.yml'
pull_request:
branches:
Expand All @@ -17,6 +18,7 @@ on:
- main
paths:
- 'api/**'
- 'db/**'
Comment thread
RobinGummels marked this conversation as resolved.
- '.github/workflows/api-ci.yml'

jobs:
Expand Down
64 changes: 63 additions & 1 deletion db/init/02_tables_catalog.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ CREATE TABLE catalog (
title TEXT,
description TEXT,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now()
updated_at TIMESTAMP DEFAULT now(),
search_vector tsvector
);

-- Catalog links table: Stores related links for catalogs (e.g., self, root, child, item links)
Expand Down Expand Up @@ -44,3 +45,64 @@ CREATE TABLE crawllog_catalog (
catalog_id INTEGER REFERENCES catalog(id) ON DELETE CASCADE,
last_crawled TIMESTAMP
);

-- ========================================
-- FULL-TEXT SEARCH TRIGGERS
-- ========================================

-- Trigger function to auto-update search_vector when catalog is inserted or updated
-- Includes title, description, and all associated keywords for comprehensive search
CREATE OR REPLACE FUNCTION update_catalog_search_vector()
RETURNS TRIGGER AS $$
BEGIN
NEW.search_vector := to_tsvector('simple',
coalesce(NEW.title, '') || ' ' ||
coalesce(NEW.description, '') || ' ' ||
coalesce(
(
SELECT string_agg(k.keyword, ' ')
FROM catalog_keywords ck
JOIN keywords k ON k.id = ck.keyword_id
WHERE ck.catalog_id = NEW.id
),
''
)
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER catalog_search_vector_update
BEFORE INSERT OR UPDATE ON catalog
FOR EACH ROW
EXECUTE FUNCTION update_catalog_search_vector();

-- Trigger function to update search_vector when keywords are added/removed
-- Ensures search index stays in sync with keyword changes
CREATE OR REPLACE FUNCTION update_catalog_search_vector_on_keyword_change()
RETURNS TRIGGER AS $$
BEGIN
UPDATE catalog
SET search_vector = to_tsvector('simple',
coalesce(title, '') || ' ' ||
coalesce(description, '') || ' ' ||
coalesce(
(
SELECT string_agg(k.keyword, ' ')
FROM catalog_keywords ck
JOIN keywords k ON k.id = ck.keyword_id
WHERE ck.catalog_id = catalog.id
),
''
)
)
WHERE id = COALESCE(NEW.catalog_id, OLD.catalog_id);

RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER catalog_keywords_update_vector
AFTER INSERT OR DELETE ON catalog_keywords
FOR EACH ROW
EXECUTE FUNCTION update_catalog_search_vector_on_keyword_change();
64 changes: 63 additions & 1 deletion db/init/03_tables_collections.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ CREATE TABLE collection (
is_api BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,

full_json JSONB
full_json JSONB,
search_vector tsvector
);

-- Collection summaries: Stores summaries for collection properties
Expand Down Expand Up @@ -64,3 +65,64 @@ CREATE TABLE crawllog_collection (
collection_id INTEGER REFERENCES collection(id) ON DELETE CASCADE,
last_crawled TIMESTAMP
);

-- ========================================
-- FULL-TEXT SEARCH TRIGGERS
-- ========================================

-- Trigger function to auto-update search_vector when collection is inserted or updated
-- Includes title, description, and all associated keywords for comprehensive search
CREATE OR REPLACE FUNCTION update_collection_search_vector()
RETURNS TRIGGER AS $$
BEGIN
NEW.search_vector := to_tsvector('simple',
coalesce(NEW.title, '') || ' ' ||
coalesce(NEW.description, '') || ' ' ||
coalesce(
(
SELECT string_agg(k.keyword, ' ')
FROM collection_keywords ck
JOIN keywords k ON k.id = ck.keyword_id
WHERE ck.collection_id = NEW.id
),
''
)
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER collection_search_vector_update
BEFORE INSERT OR UPDATE ON collection
FOR EACH ROW
EXECUTE FUNCTION update_collection_search_vector();

-- Trigger function to update search_vector when keywords are added/removed
-- Ensures search index stays in sync with keyword changes
CREATE OR REPLACE FUNCTION update_collection_search_vector_on_keyword_change()
RETURNS TRIGGER AS $$
BEGIN
UPDATE collection
SET search_vector = to_tsvector('simple',
coalesce(title, '') || ' ' ||
coalesce(description, '') || ' ' ||
coalesce(
(
SELECT string_agg(k.keyword, ' ')
FROM collection_keywords ck
JOIN keywords k ON k.id = ck.keyword_id
WHERE ck.collection_id = collection.id
),
''
)
)
WHERE id = COALESCE(NEW.collection_id, OLD.collection_id);

RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER collection_keywords_update_vector
AFTER INSERT OR DELETE ON collection_keywords
FOR EACH ROW
EXECUTE FUNCTION update_collection_search_vector_on_keyword_change();
8 changes: 4 additions & 4 deletions db/init/05_indexes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
CREATE INDEX idx_catalog_title ON catalog (title);
CREATE INDEX idx_catalog_updated_at ON catalog (updated_at);

CREATE INDEX idx_catalog_fulltext ON catalog
USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,'')));
-- Full-text search index on computed search_vector column (includes title, description, and keywords)
CREATE INDEX idx_catalog_search_vector ON catalog USING GIN (search_vector);

CREATE INDEX idx_catalog_links_catalog_id ON catalog_links (catalog_id);
CREATE INDEX idx_catalog_keywords_catalog ON catalog_keywords (catalog_id);
Expand All @@ -30,8 +30,8 @@ CREATE INDEX idx_collection_active ON collection (is_active);

CREATE INDEX idx_collection_spatial ON collection USING GIST (spatial_extent);

CREATE INDEX idx_collection_fulltext ON collection
USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,'')));
-- Full-text search index on computed search_vector column (includes title, description, and keywords)
CREATE INDEX idx_collection_search_vector ON collection USING GIN (search_vector);

CREATE INDEX idx_collection_jsonb ON collection USING GIN (full_json);

Expand Down
Loading