← back to Handbag Authentication

scripts/setup-search-fixed.sql

163 lines

-- Setup Full-Text Search for LUXVAULT Database
-- This script creates comprehensive search capabilities for all data

-- Create Full-Text Search virtual table for listings
CREATE VIRTUAL TABLE IF NOT EXISTS listings_fts USING fts5(
    external_id,
    source,
    title,
    brand,
    model,
    condition,
    location,
    seller_name,
    description,
    content=listings,
    content_rowid=id
);

-- Populate the FTS table with existing data
INSERT OR REPLACE INTO listings_fts (
    external_id, source, title, brand, model, 
    condition, location, seller_name, description
)
SELECT 
    external_id, source, title, brand, model,
    condition, location, seller_name, description
FROM listings;

-- Create triggers to keep FTS in sync
CREATE TRIGGER IF NOT EXISTS listings_ai 
AFTER INSERT ON listings 
BEGIN
    INSERT INTO listings_fts (
        external_id, source, title, brand, model,
        condition, location, seller_name, description
    ) VALUES (
        new.external_id, new.source, new.title, new.brand, new.model,
        new.condition, new.location, new.seller_name, new.description
    );
END;

CREATE TRIGGER IF NOT EXISTS listings_ad 
AFTER DELETE ON listings 
BEGIN
    DELETE FROM listings_fts WHERE rowid = old.id;
END;

CREATE TRIGGER IF NOT EXISTS listings_au 
AFTER UPDATE ON listings 
BEGIN
    UPDATE listings_fts SET
        external_id = new.external_id,
        source = new.source,
        title = new.title,
        brand = new.brand,
        model = new.model,
        condition = new.condition,
        location = new.location,
        seller_name = new.seller_name,
        description = new.description
    WHERE rowid = new.id;
END;

-- Create comprehensive indexes for fast searching
CREATE INDEX IF NOT EXISTS idx_listings_brand_model ON listings(brand, model);
CREATE INDEX IF NOT EXISTS idx_listings_price_range ON listings(price_usd, price_jpy);
CREATE INDEX IF NOT EXISTS idx_listings_condition ON listings(condition);
CREATE INDEX IF NOT EXISTS idx_listings_source ON listings(source);
CREATE INDEX IF NOT EXISTS idx_listings_seller ON listings(seller_name);
CREATE INDEX IF NOT EXISTS idx_listings_location ON listings(location);
CREATE INDEX IF NOT EXISTS idx_listings_title ON listings(title);
CREATE INDEX IF NOT EXISTS idx_listings_description ON listings(description);

-- Create a view for easy searching with all data
CREATE VIEW IF NOT EXISTS searchable_listings AS
SELECT 
    l.id,
    l.external_id,
    l.source,
    l.title,
    l.brand,
    l.model,
    l.price_jpy,
    l.price_usd,
    l.condition,
    l.image_url,
    l.thumbnail_url,
    l.product_url,
    l.listing_type,
    l.auction_end_date,
    l.location,
    l.seller_name,
    l.description,
    l.crawled_at,
    da.deal_percentage,
    da.avg_us_price,
    da.is_deal,
    CASE 
        WHEN l.image_url IS NOT NULL THEN 'Yes'
        ELSE 'No'
    END as has_image,
    CASE 
        WHEN l.title LIKE '%birkin%' OR l.title LIKE '%バーキン%' THEN 'Birkin'
        WHEN l.title LIKE '%kelly%' OR l.title LIKE '%ケリー%' THEN 'Kelly'
        WHEN l.title LIKE '%constance%' OR l.title LIKE '%コンスタンス%' THEN 'Constance'
        WHEN l.title LIKE '%neverfull%' OR l.title LIKE '%ネヴァーフル%' THEN 'Neverfull'
        WHEN l.title LIKE '%speedy%' OR l.title LIKE '%スピーディ%' THEN 'Speedy'
        WHEN l.title LIKE '%classic flap%' OR l.title LIKE '%クラシック%' THEN 'Classic Flap'
        WHEN l.model IS NOT NULL THEN l.model
        ELSE 'Other'
    END as detected_model,
    CASE 
        WHEN l.title LIKE '%black%' OR l.title LIKE '%ブラック%' OR l.title LIKE '%黒%' THEN 'Black'
        WHEN l.title LIKE '%brown%' OR l.title LIKE '%ブラウン%' OR l.title LIKE '%茶%' THEN 'Brown'
        WHEN l.title LIKE '%red%' OR l.title LIKE '%レッド%' OR l.title LIKE '%赤%' THEN 'Red'
        WHEN l.title LIKE '%blue%' OR l.title LIKE '%ブルー%' OR l.title LIKE '%青%' THEN 'Blue'
        WHEN l.title LIKE '%white%' OR l.title LIKE '%ホワイト%' OR l.title LIKE '%白%' THEN 'White'
        WHEN l.title LIKE '%pink%' OR l.title LIKE '%ピンク%' THEN 'Pink'
        WHEN l.title LIKE '%gold%' OR l.title LIKE '%ゴールド%' OR l.title LIKE '%金%' THEN 'Gold'
        ELSE NULL
    END as detected_color,
    CASE 
        WHEN l.title LIKE '%leather%' OR l.title LIKE '%レザー%' OR l.title LIKE '%革%' THEN 'Leather'
        WHEN l.title LIKE '%canvas%' OR l.title LIKE '%キャンバス%' THEN 'Canvas'
        WHEN l.title LIKE '%suede%' OR l.title LIKE '%スエード%' THEN 'Suede'
        WHEN l.title LIKE '%crocodile%' OR l.title LIKE '%クロコダイル%' THEN 'Crocodile'
        WHEN l.title LIKE '%python%' OR l.title LIKE '%パイソン%' THEN 'Python'
        ELSE NULL
    END as detected_material
FROM listings l
LEFT JOIN deal_analysis da ON l.id = da.listing_id;

-- Add metadata table for tracking searches
CREATE TABLE IF NOT EXISTS search_history (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    search_query TEXT NOT NULL,
    results_count INTEGER,
    search_type TEXT,
    searched_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Create a table for image metadata
CREATE TABLE IF NOT EXISTS image_metadata (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    listing_id INTEGER,
    image_url TEXT,
    thumbnail_url TEXT,
    image_hash TEXT,
    image_size INTEGER,
    has_logo INTEGER DEFAULT 0,
    primary_color TEXT,
    indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY(listing_id) REFERENCES listings(id) ON DELETE CASCADE
);

-- Index for image searching
CREATE INDEX IF NOT EXISTS idx_image_url ON image_metadata(image_url);
CREATE INDEX IF NOT EXISTS idx_image_hash ON image_metadata(image_hash);
CREATE INDEX IF NOT EXISTS idx_image_color ON image_metadata(primary_color);

-- Analyze tables for query optimization
ANALYZE listings;
ANALYZE listings_fts;