Skip to content

WP_PRODUCTS

This is based on the custom wp_products table with associated queries.

-- ============================================
-- FULL TEXT SEARCH SETUP FOR wp_products
-- ============================================

-- Create the wp_products table with auto-increment ID and GUID product_id
CREATE TABLE IF NOT EXISTS wp_products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    product_id CHAR(36) NOT NULL UNIQUE,
    product_name VARCHAR(255) NOT NULL,
    product_short_description VARCHAR(500),
    expanded_description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_product_id (product_id),
    INDEX idx_product_name (product_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 1. CREATE FULL TEXT INDEXES
-- ============================================

-- Index on product_name only
ALTER TABLE wp_products 
ADD FULLTEXT INDEX ft_product_name (product_name);

-- Index on product_short_description only
ALTER TABLE wp_products 
ADD FULLTEXT INDEX ft_short_desc (product_short_description);

-- Index on product_short_description only
ALTER TABLE wp_products 
ADD FULLTEXT INDEX ft_expanded_description (expanded_description);
-- Composite index on multiple columns (recommended for comprehensive search)
ALTER TABLE wp_products 
ADD FULLTEXT INDEX ft_product_search (product_name, product_short_description, expanded_description);
-- More ropbust way
-- Stored procedure to check and create full-text indexes if they don't exist
DELIMITER $$

DROP PROCEDURE IF EXISTS ensure_wp_products_fulltext_indexes$$

CREATE PROCEDURE ensure_wp_products_fulltext_indexes()
BEGIN
    -- ft_product_name
    IF NOT EXISTS (
        SELECT 1
        FROM information_schema.statistics
        WHERE table_schema = DATABASE()
          AND table_name = 'wp_products'
          AND index_name = 'ft_product_name'
    ) THEN
        ALTER TABLE wp_products
        ADD FULLTEXT INDEX ft_product_name (product_name);
    END IF;

    -- ft_short_desc
    IF NOT EXISTS (
        SELECT 1
        FROM information_schema.statistics
        WHERE table_schema = DATABASE()
          AND table_name = 'wp_products'
          AND index_name = 'ft_short_desc'
    ) THEN
        ALTER TABLE wp_products
        ADD FULLTEXT INDEX ft_short_desc (product_short_description);
    END IF;

    -- ft_expanded_description
    IF NOT EXISTS (
        SELECT 1
        FROM information_schema.statistics
        WHERE table_schema = DATABASE()
          AND table_name = 'wp_products'
          AND index_name = 'ft_expanded_description'
    ) THEN
        ALTER TABLE wp_products
        ADD FULLTEXT INDEX ft_expanded_description (expanded_description);
    END IF;

    -- ft_product_search (composite)
    IF NOT EXISTS (
        SELECT 1
        FROM information_schema.statistics
        WHERE table_schema = DATABASE()
          AND table_name = 'wp_products'
          AND index_name = 'ft_product_search'
    ) THEN
        ALTER TABLE wp_products
        ADD FULLTEXT INDEX ft_product_search (
            product_name,
            product_short_description,
            expanded_description
        );
    END IF;
END$$

DELIMITER ;

CALL ensure_wp_products_fulltext_indexes();

-- Optional: clean up
DROP PROCEDURE ensure_wp_products_fulltext_indexes;
-- ============================================
-- 2. NATURAL LANGUAGE MODE QUERIES
-- ============================================
-- Default mode - searches for words in natural text
-- Results ranked by relevance automaticall
-- !! There must be an index on the  composite searched columns !!
-- If you MATCH against multiple columns, ensure a FULLTEXT index exists on all those columns, not just individual columns.


-- Basic natural language search
SELECT id, product_name, product_short_description, expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('wireless audio') AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('wireless audio')
ORDER BY relevance_score DESC;
-- Search for camera products
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('camera video recording') AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('camera video recording')
ORDER BY relevance_score DESC;
-- Search for workspace/office products
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('desk workspace office') AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('desk workspace office')
ORDER BY relevance_score DESC;
-- Combine full-text with regular WHERE clause
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('smart home') AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('smart home')
  AND created_at >= '2026-01-01'
ORDER BY relevance_score DESC;
-- ============================================
-- 3. BOOLEAN MODE QUERIES
-- ============================================
-- More control with operators: +required -excluded "phrase" *wildcard

-- Search with required terms (+ operator)
-- Must contain "smart" AND "LED"
-- LED is in expanded_description for Smart Indoor Garden Kit
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('+smart +LED' IN BOOLEAN MODE);
-- Search with excluded terms (- operator)
-- Contains "speaker" and optionally "bluetooth"
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('+speaker bluetooth' IN BOOLEAN MODE);
-- Phrase search with quotes
-- Exact phrase "noise cancelling"
SELECT product_name, product_short_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('"noise cancelling"' IN BOOLEAN MODE);
-- Wildcard search (* operator)
-- Matches "port", "portable", "portability", etc.
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('port*' IN BOOLEAN MODE);
-- Complex boolean query combining operators
-- Must have "camera" OR "speaker", must have "portable", cannot have "desk"
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('+(camera speaker) +portable -desk' IN BOOLEAN MODE);
-- Optional terms with relevance boosting (> and < operators)
-- "wireless" is more important, "audio" is less important
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('>wireless <audio' IN BOOLEAN MODE);
-- Search for products with specific features
-- Must contain "waterproof" or "water-resistant" or "splash-resistant"
SELECT id, product_name, product_short_description,expanded_description
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('+water* +(proof resistant)' IN BOOLEAN MODE);
-- ============================================
-- 4. QUERY EXPANSION MODE
-- ============================================
-- Automatically expands search with related terms
-- Two-pass search: first finds relevant docs, then adds related terms

-- Basic query expansion
-- Finds "bluetooth" and related terms like "wireless", "connectivity", etc.
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('bluetooth' WITH QUERY EXPANSION) AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('bluetooth' WITH QUERY EXPANSION)
ORDER BY relevance_score DESC;
-- Search for audio products with expansion
-- Will find "audio", "sound", "speaker", "music", etc.
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('audio' WITH QUERY EXPANSION) AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('audio' WITH QUERY EXPANSION)
ORDER BY relevance_score DESC;
-- Search for fitness products with expansion
-- Will find related terms to "yoga" like "exercise", "fitness", "workout"
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('yoga' WITH QUERY EXPANSION) AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('yoga' WITH QUERY EXPANSION)
ORDER BY relevance_score DESC;
-- ============================================
-- 5. PRACTICAL WORDPRESS INTEGRATION EXAMPLES
-- ============================================

-- Search with pagination (for WordPress product listings)
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('smart home' WITH QUERY EXPANSION) AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('smart home' WITH QUERY EXPANSION)
ORDER BY relevance_score DESC
LIMIT 10 OFFSET 0;
-- Search with minimum relevance threshold
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(product_name, product_short_description, expanded_description) 
       AGAINST ('wireless portable') AS relevance_score
FROM wp_products
WHERE MATCH(product_name, product_short_description, expanded_description) 
      AGAINST ('wireless portable')
HAVING relevance_score > 0.5
ORDER BY relevance_score DESC;
-- Combined search: Full-text + category filter (if you add categories)
-- This example assumes you might join with a categories table
SELECT id, product_name, product_short_description,expanded_description,
       MATCH(p.product_name, p.product_short_description, p.expanded_description) 
       AGAINST ('+audio +wireless' IN BOOLEAN MODE) AS relevance_score
FROM wp_products p
WHERE MATCH(p.product_name, p.product_short_description, p.expanded_description) 
      AGAINST ('+audio +wireless' IN BOOLEAN MODE)
ORDER BY relevance_score DESC;

PERFORMANCE TIPS & NOTES

  1. Minimum word length: By default, MySQL ignores words shorter than 4 characters
  2. Configure with ft_min_word_len in my.cnf
  3. Rebuild indexes after changing: REPAIR TABLE wp_products QUICK;

  4. Stopwords: Common words (the, and, or, etc.) are ignored

  5. Configure custom stopword list if needed

  6. Boolean operators:

  7. : Must contain this word
  8. : Must NOT contain this word

    : Increase relevance < : Decrease relevance

  9. : Wildcard (must be at end of word) " : Exact phrase match () : Grouping

  10. Query Expansion:

  11. Useful for semantic search
  12. Can return more results than expected
  13. Slower than natural/boolean mode
  14. Best for short queries (1-2 words)

  15. Performance:

  16. Full-text indexes are fast for searching
  17. Can slow down INSERT/UPDATE operations
  18. Consider using separate search table for high-volume sites

  19. WordPress Integration:

  20. Use prepared statements in wpdb
  21. Example: $wpdb->prepare() with %s for search terms
  22. Sanitize user input before search queries
-- Check full-text index status
SHOW INDEX FROM wp_products WHERE Index_type = 'FULLTEXT';

-- Analyze table performance
ANALYZE TABLE wp_products;