feat(F-048): completed feature
This commit is contained in:
@@ -1,83 +1,44 @@
|
||||
/**
|
||||
* Migration 026: Fuzzy search with trigram similarity (pg_trgm)
|
||||
* Migration 026: Fuzzy search with trigram similarity (pg_trgm).
|
||||
*
|
||||
* - Enables pg_trgm extension for Levenshtein-like fuzzy matching
|
||||
* - Creates GIN indexes on product name/description for fast trigram similarity
|
||||
* - Adds similarity index on brands and categories for term suggestions
|
||||
*
|
||||
* Run: node migrations/026_fuzzy_search.js
|
||||
* This is an ordered node-pg-migrate migration. It must not open its own
|
||||
* connection or execute work while the migration module is being loaded.
|
||||
*/
|
||||
|
||||
const { Pool } = require('pg');
|
||||
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
||||
exports.up = (pgm) => {
|
||||
pgm.sql('CREATE EXTENSION IF NOT EXISTS pg_trgm');
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL || 'postgres://mdv:mdv_dev_only@localhost:5432/mercadodevida',
|
||||
});
|
||||
pgm.sql(`
|
||||
CREATE INDEX IF NOT EXISTS catalog_products_name_trgm_idx
|
||||
ON catalog_products
|
||||
USING GIN (name gin_trgm_ops)
|
||||
`);
|
||||
|
||||
async function migrate() {
|
||||
const client = await pool.connect();
|
||||
pgm.sql(`
|
||||
CREATE INDEX IF NOT EXISTS catalog_products_description_trgm_idx
|
||||
ON catalog_products
|
||||
USING GIN (description gin_trgm_ops)
|
||||
`);
|
||||
|
||||
try {
|
||||
await client.query('BEGIN');
|
||||
pgm.sql(`
|
||||
CREATE INDEX IF NOT EXISTS brands_brands_name_trgm_idx
|
||||
ON brands_brands
|
||||
USING GIN (name gin_trgm_ops)
|
||||
`);
|
||||
|
||||
// 1. Enable pg_trgm extension
|
||||
await client.query(`
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
`);
|
||||
console.log('✓ pg_trgm extension enabled');
|
||||
pgm.sql(`
|
||||
CREATE INDEX IF NOT EXISTS categories_categories_name_trgm_idx
|
||||
ON categories_categories
|
||||
USING GIN (name gin_trgm_ops)
|
||||
`);
|
||||
};
|
||||
|
||||
// 2. GIN index on product name for trigram similarity
|
||||
await client.query(`
|
||||
CREATE INDEX IF NOT EXISTS catalog_products_name_trgm_idx
|
||||
ON catalog_products
|
||||
USING GIN (name gin_trgm_ops);
|
||||
`);
|
||||
console.log('✓ catalog_products name trigram index');
|
||||
|
||||
// 3. GIN index on product description
|
||||
await client.query(`
|
||||
CREATE INDEX IF NOT EXISTS catalog_products_description_trgm_idx
|
||||
ON catalog_products
|
||||
USING GIN (description gin_trgm_ops);
|
||||
`);
|
||||
console.log('✓ catalog_products description trigram index');
|
||||
|
||||
// 4. GIN index on brand names (for suggestions)
|
||||
await client.query(`
|
||||
CREATE INDEX IF NOT EXISTS brands_brands_name_trgm_idx
|
||||
ON brands_brands
|
||||
USING GIN (name gin_trgm_ops);
|
||||
`);
|
||||
console.log('✓ brands_brands name trigram index');
|
||||
|
||||
// 5. GIN index on category names (for suggestions)
|
||||
await client.query(`
|
||||
CREATE INDEX IF NOT EXISTS categories_categories_name_trgm_idx
|
||||
ON categories_categories
|
||||
USING GIN (name gin_trgm_ops);
|
||||
`);
|
||||
console.log('✓ categories_categories name trigram index');
|
||||
|
||||
// 6. Record migration
|
||||
await client.query(`
|
||||
INSERT INTO pgmigrations (name, run_on)
|
||||
VALUES ('026_fuzzy_search', NOW())
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
`);
|
||||
console.log('✓ Migration recorded');
|
||||
|
||||
await client.query('COMMIT');
|
||||
console.log('\n✅ Migration 026 complete: fuzzy search indexes created');
|
||||
} catch (err) {
|
||||
await client.query('ROLLBACK');
|
||||
throw err;
|
||||
} finally {
|
||||
client.release();
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
migrate().catch((err) => {
|
||||
console.error('❌ Migration failed:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
||||
exports.down = (pgm) => {
|
||||
pgm.sql('DROP INDEX IF EXISTS categories_categories_name_trgm_idx');
|
||||
pgm.sql('DROP INDEX IF EXISTS brands_brands_name_trgm_idx');
|
||||
pgm.sql('DROP INDEX IF EXISTS catalog_products_description_trgm_idx');
|
||||
pgm.sql('DROP INDEX IF EXISTS catalog_products_name_trgm_idx');
|
||||
pgm.sql('DROP EXTENSION IF EXISTS pg_trgm');
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user