Skip to content

Implemented PostgreSQL full-text search on the course table, added a tsvector generated column with GIN index, replaced the ILIKE '%query%' predicate with @@ plainto_tsquery, and added ts_rank relevance-based ordering. Removed an unused test import; entity unchanged since the column is DB-managed.#939

Closed
DevScoopee wants to merge 2 commits into
rinafcode:mainfrom
DevScoopee:main

Conversation

@DevScoopee

Copy link
Copy Markdown

A new migration (1763000000000) adds search_vector tsvector to course, generated from title and description via to_tsvector('english', ...) and indexed with GIN. SearchService.search() was rewritten to use course.search_vector @@ plainto_tsquery('english', :query) instead of the non-sargable ILIKE '%query%', enabling index scans that meet the <50ms P95 target. When no explicit sort is given and a query is present, results default to ts_rank() descending for relevance ranking. The test spec had an unused import cleaned up; its mock builder is fully compatible via chainable this returns. The entity was left unchanged since TypeORM's createQueryBuilder handles unmapped columns in raw SQL expressions.

Closes #814

@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@DevScoopee Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Kindly resolve conflict

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Conflict not resolved

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Kindly resolve conflict

@DevScoopee

DevScoopee commented Jun 29, 2026 via email

Copy link
Copy Markdown
Author

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Pull from main before pushing. Conflict not resolved.

@DevScoopee DevScoopee closed this by deleting the head repository Jun 29, 2026
…a tsvector generated column with GIN index, replaced the ILIKE '%query%' predicate with @@ plainto_tsquery, and added ts_rank relevance-based ordering. Removed an unused test import; entity unchanged since the column is DB-managed.

A new migration (1763000000000) adds search_vector tsvector to course, generated from title and description via to_tsvector('english', ...) and indexed with GIN. SearchService.search() was rewritten to use course.search_vector @@ plainto_tsquery('english', :query) instead of the non-sargable ILIKE '%query%', enabling index scans that meet the <50ms P95 target. When no explicit sort is given and a query is present, results default to ts_rank() descending for relevance ranking. The test spec had an unused import cleaned up; its mock builder is fully compatible via chainable this returns. The entity was left unchanged since TypeORM's createQueryBuilder handles unmapped columns in raw SQL expressions.

Closes #814
…a tsvector generated column with GIN index, replaced the ILIKE '%query%' predicate with @@ plainto_tsquery, and added ts_rank relevance-based ordering. Removed an unused test import; entity unchanged since the column is DB-managed.

 A new migration (1763000000000) adds search_vector tsvector to course, generated from title and description via to_tsvector('english', ...) and indexed with GIN. SearchService.search() was rewritten to use course.search_vector @@ plainto_tsquery('english', :query) instead of the non-sargable ILIKE '%query%', enabling index scans that meet the <50ms P95 target. When no explicit sort is given and a query is present, results default to ts_rank() descending for relevance ranking. The test spec had an unused import cleaned up; its mock builder is fully compatible via chainable this returns. The entity was left unchanged since TypeORM's createQueryBuilder handles unmapped columns in raw SQL expressions.

Closes #814
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Course search uses ILIKE without full-text index causing full table scans

2 participants