Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

AI Powered Search for Laravel Products

By Kokil Thapa | Last reviewed: August 2026

Implementing AI powered search for Laravel products requires moving beyond simple SQL LIKE queries or basic full-text indexes to embrace semantic understanding and vector embeddings. In my experience building eCommerce platforms like Nepal Gift Card and various WooCommerce stores, users expect search to understand intent ("red dress for wedding") rather than just matching exact keywords. This guide covers the practical integration of Laravel Scout with Meilisearch and OpenAI-compatible embedding APIs to build a production-grade semantic search system that actually converts.

If you are new to optimizing catalog architecture before adding AI layers, review our guide on scalable product catalog architecture for e-commerce to ensure your database schema supports efficient indexing. A solid foundation prevents expensive rework once vectors enter the picture.

How does AI powered search for Laravel products differ from standard Scout?

Standard Laravel Scout provides an excellent abstraction over search engines like Algolia or Meilisearch, but out of the box, it primarily handles lexical (keyword) matching. When a customer searches "warm winter jacket", traditional search looks for documents containing those specific tokens. It fails if your product is titled "Thermal Insulated Parka" without the word "jacket". AI powered search for Laravel products solves this by mapping both the query and the product description into a high-dimensional vector space where meaning, not spelling, determines proximity.

Traditional Keyword SearchQuery: "Red Wedding Dress"SQL LIKE / Full Text MatchRequires exact token overlapMisses: "Crimson Bridal Gown"Result: 0 Matches FoundAI Powered Semantic SearchQuery: "Red Wedding Dress"Vector Embedding + Cosine SimMatches conceptual meaningFinds: "Crimson Bridal Gown"Result: Relevant Products Ranked
Keyword search fails on synonyms while AI powered search for Laravel products uses vector embeddings to match user intent semantically.

In practice, this means your Laravel application must perform two distinct operations during indexing: generating searchable text attributes for typo tolerance and generating dense vector representations for semantic matching. Meilisearch v1.12+ supports native vector storage and hybrid search, making it the most pragmatic choice for Laravel developers in 2026 who want self-hosted infrastructure without the per-query costs of managed SaaS providers. For teams evaluating backend options, our comparison of Laravel Meilisearch integration covers baseline setup before adding vectors.

How do you generate and store vector embeddings in Laravel?

The core of AI powered search for Laravel products is the embedding generation pipeline. You need to convert product titles, descriptions, and attributes into numerical vectors whenever a model is created or updated. While you can call external APIs synchronously during saves, this creates latency and failure points. On production eCommerce sites I maintain, we always decouple embedding generation using Laravel Queues.

Creating the Embedding Job

Create a dedicated job that handles API communication and retries. Never embed inside the controller or model observer directly.

<?php

namespace App\Jobs;

use App\Models\Product;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class GenerateProductEmbedding implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $backoff = 60;

    public function __construct(
        private Product $product
    ) {}

    public function handle(): void
    {
        $textToEmbed = sprintf(
            '%s %s %s',
            $this->product->name,
            $this->product->short_description,
            $this->product->category?->name ?? ''
        );

        try {
            $response = Http::timeout(30)->withToken(config('services.embedding_api_key'))
                ->post('https://api.openai.com/v1/embeddings', [
                    'model' => 'text-embedding-3-small',
                    'input' => $textToEmbed,
                    'dimensions' => 1024,
                ]);

            if ($response->successful()) {
                $vector = $response->json('data.0.embedding');
                
                // Store vector separately to avoid bloating main table
                $this->product->embedding()->updateOrCreate(
                    ['product_id' => $this->product->id],
                    ['vector' => json_encode($vector)]
                );
                
                // Trigger Scout re-index to push vector to Meilisearch
                $this->product->searchable();
            }
        } catch (\Exception $e) {
            Log::error('Embedding generation failed', [
                'product_id' => $this->product->id,
                'error' => $e->getMessage(),
            ]);
            throw $e;
        }
    }
}

This job targets OpenAI’s text-embedding-3-small model with 1024 dimensions, which offers the best cost-to-performance ratio for product catalogs in 2026. If you are operating under strict data residency requirements or budget constraints common in Nepal-based projects, consider running nomic-embed-text or bge-m3 locally via Ollama on the same VPS. Local models eliminate API costs entirely but require sufficient RAM (minimum 8GB dedicated to inference).

Integrating with Model Observers

Dispatch the job from an observer to keep controllers clean. Always check if the relevant fields actually changed before regenerating embeddings to save API credits.

class ProductObserver
{
    public function saved(Product $product): void
    {
        if ($product->wasChanged(['name', 'short_description', 'category_id'])) {
            GenerateProductEmbedding::dispatch($product);
        }
    }
}

For large existing catalogs, never run synchronous bulk embedding. Use Scout’s scout:import command combined with a custom Artisan command that chunks products and dispatches jobs with rate limiting to respect API quotas. A typical 10,000-product catalog takes 2–4 hours to embed at standard rate limits.

How do you configure Meilisearch for hybrid search in Laravel?

Once vectors exist in your database, Meilisearch needs explicit configuration to use them alongside keyword matching. Hybrid search combines BM25 textual relevance with vector cosine similarity, weighted by a parameter you tune based on your catalog’s characteristics. Pure vector search often misses exact SKU matches; pure keyword search misses synonyms. Hybrid gives you both.

User Query"Summer Hat"BM25 Keyword EngineExact + Typo ToleranceVector EngineCosine SimilarityHybrid RankerWeighted Score Fusion(semanticWeight: 0.7)Ranked ResultsReturned to UI
Hybrid search architecture combining BM25 keyword matching and vector similarity for AI powered search for Laravel products.

Configuring Index Settings

Add vector configuration to your Scout config or apply it programmatically via the Meilisearch PHP SDK during deployment. This step is frequently missed in tutorials.

// In a custom Artisan command or deploy script
$client = new \Meilisearch\Client(config('scout.meilisearch.host'), config('scout.meilisearch.key'));

$client->index('products')->updateSettings([
    'embedders' => [
        'default' => [
            'source' => 'userProvided',
            'dimensions' => 1024,
        ],
    ],
    'searchableAttributes' => [
        'name',
        'sku',
        'short_description',
        'category_name',
        'tags',
    ],
    'filterableAttributes' => ['price', 'category_id', 'in_stock', 'brand'],
    'sortableAttributes' => ['price', 'created_at'],
]);

Note source: userProvided. This tells Meilisearch you are supplying pre-computed vectors rather than asking it to call an embedding API itself. This is critical for Laravel applications because it keeps embedding logic within your application boundary where you control caching, rate limiting, and model selection.

Executing Hybrid Searches

Laravel Scout’s builder doesn’t natively expose hybrid parameters as of 2026. You need to extend the builder or use the Meilisearch engine directly for advanced queries.

use Laravel\Scout\Builder;
use Meilisearch\Client;

$meilisearch = new Client(config('scout.meilisearch.host'), config('scout.meilisearch.key'));

$results = $meilisearch->index('products')->search($query, [
    'hybrid' => [
        'semanticRatio' => 0.7,
        'embedder' => 'default',
    ],
    'vector' => $queryVector, // Generated from user query at request time
    'limit' => 20,
    'filter' => 'in_stock = true AND price <= ' . $maxPrice,
]);

The semanticRatio controls the balance. Start at 0.7 for fashion/lifestyle catalogs where synonym matching matters heavily. Drop to 0.3–0.5 for technical/electronics catalogs where exact model numbers dominate. Test with real user queries from your analytics before committing to a value.

Adding AI powered search for Laravel products introduces computational overhead that must be planned for, especially when hosting in Nepal or on budget VPS instances. Understanding these trade-offs prevents surprise bills and degraded UX.

FactorStandard Scout (BM25)AI Powered Hybrid Search
Indexing Latency< 100ms per document200–800ms + embedding API call
Query Latency5–20ms15–50ms (includes query embedding)
Storage per Product~2–5 KB~6–10 KB (vectors add ~4KB @ 1024 dims)
RAM Requirements512MB–1GB for 100K docs2–4GB for 100K docs with vectors
Ongoing CostServer onlyServer + embedding API (~$0.02/1M tokens)
Relevance QualityGood for exact matchesSuperior for intent/synonyms

Query-time embedding is the hidden bottleneck. Every search request must embed the user’s query before hitting Meilisearch. Cache aggressively. For an eCommerce site serving Kathmandu customers, I cache query embeddings in Redis with a 1-hour TTL keyed by normalized query string. This reduces API calls by 60–80% for popular searches and cuts p95 latency from 120ms to 25ms.

// Cache query embeddings in your search service
$cacheKey = 'search_embedding:' . md5(strtolower(trim($query)));

$queryVector = Cache::remember($cacheKey, 3600, function () use ($query) {
    return $this->embeddingService->generate($query);
});

For teams concerned about vendor lock-in or API availability, local embedding models via Ollama provide zero-cost alternatives at the expense of GPU/CPU resources. The nomic-embed-text model runs comfortably on a 4-core 8GB VPS and produces 768-dimension vectors compatible with Meilisearch. This is often the right choice for Nepal-based legal-tech portals or SMB eCommerce sites where margins are thin and traffic is predictable. Learn more about balancing performance in our article on improving web performance with caching strategies.

How do you evaluate and tune semantic search relevance?

Deploying AI powered search for Laravel products without evaluation leads to silent failures where results look plausible but miss key items. Establish a ground-truth test set before going live. Collect 50–100 real user queries from your logs and manually label the top 5 expected results for each.

  1. Build an automated relevance test suite using PHPUnit or Pest that runs your labeled queries against the search index and calculates NDCG@5 (Normalized Discounted Cumulative Gain). Track this metric in CI.
  2. A/B test semantic ratios in production using feature flags. Serve 0.5, 0.7, and 0.9 to different user cohorts and measure click-through rate and conversion, not just relevance scores.
  3. Monitor zero-result rates daily. A spike usually indicates embedding model drift, API failures, or new product categories lacking proper metadata.
  4. Implement fallback logic: if hybrid search returns fewer than 3 results above a confidence threshold, automatically retry with pure BM25. This prevents empty pages when the vector model misinterprets niche terminology.
Run Relevance Test SuiteNDCG@5 > 0.8?NoYesAdjust Weightsor Improve MetadataRetest & ValidateAgainst Ground TruthDeploy to ProductionWith MonitoringTrack CTR &Zero-Result RateMetrics Stable?No → Retune✓ Done
Iterative evaluation workflow for maintaining relevance quality in AI powered search for Laravel products.

On a legal-tech portal I built, initial vector search performed poorly for Nepali legal terminology because English-trained embedding models didn’t capture local context. We solved this by prepending English translations to the indexed text and boosting exact-match Nepali terms via filterable attributes. This hybrid approach preserved semantic discovery while respecting domain-specific precision needs. Always validate assumptions against your actual user base, not benchmark leaderboards.

Practical Next Steps for Your Laravel Search Implementation

AI powered search for Laravel products delivers measurable conversion improvements when implemented correctly, but it demands disciplined engineering over hype. Start with Meilisearch hybrid search using pre-computed embeddings, cache query vectors aggressively, and establish relevance testing before scaling. Avoid over-engineering: most eCommerce catalogs under 100,000 SKUs perform excellently on a single 4GB VPS with this stack. Monitor costs, tune semantic ratios based on real behavior, and remember that search quality is a product decision, not just a technical one. If you need hands-on implementation support for your Laravel eCommerce platform or legal-tech portal, get in touch to discuss your specific requirements.

Frequently Asked Questions

It integrates vector embeddings and semantic matching into Laravel applications, allowing users to find products by intent and natural language rather than exact keyword matches in MySQL.

Custom integration typically costs NPR 80,000 to 250,000 (USD 600–1,900) depending on catalog size, plus monthly API or hosting fees for the vector database infrastructure.

Use AI search when customers describe needs conceptually like "gift for elderly father" rather than specific SKUs, or when keyword search consistently returns irrelevant results despite tuning.

For most Laravel product catalogs under 100,000 items, I recommend Meilisearch 1.12 or Typesense 2.0 because they offer native Laravel Scout drivers, hybrid search combining keywords with vectors, and simple self-hosting on Ubuntu. Pinecone or Weaviate make sense only for massive catalogs exceeding one million products where managed infrastructure justifies the added complexity and cost. On client eCommerce projects, I have found self-hosted options significantly reduce long-term operational expenses compared to managed vector services.

Use open-source models like bge-m3 or e5-mistral-7b-instruct via Ollama on your existing server for catalogs under 50,000 products. This eliminates per-query API costs entirely. For larger catalogs or higher quality requirements, OpenAI text-embedding-3-small costs roughly USD 0.02 per million tokens, which translates to about NPR 500 for indexing 10,000 products. In my experience building eCommerce platforms, batch embedding generation during off-peak hours prevents performance degradation on production servers serving live traffic.

No, hybrid search combining both approaches consistently outperforms pure vector search for product catalogs. Vector search excels at semantic understanding but struggles with exact SKU matching, model numbers, and brand names. Configure Laravel Scout to query both the vector index and MySQL full-text index, then merge results using reciprocal rank fusion. On legal-tech portals and eCommerce sites I have built, this hybrid approach reduced zero-result queries by over forty percent compared to vector-only implementations while maintaining precise matching for technical product identifiers.

Implement Laravel model observers or event listeners on Product created, updated, and deleted events to trigger asynchronous embedding regeneration via queued jobs. Never regenerate embeddings synchronously during HTTP requests as this blocks user interactions. Use a dedicated queue worker with rate limiting to prevent overwhelming your embedding provider. For bulk imports via Laravel Excel, dispatch batch embedding jobs after import completion rather than per-row. I have seen production systems fail when teams skip this async pattern and embed generation saturates API rate limits during catalog updates.

Primary risks include prompt injection through search queries manipulating embedding retrieval, data leakage via overly broad semantic matches exposing restricted products, and API key exposure in frontend code. Always validate and sanitize search input server-side before embedding generation. Implement row-level access control filtering on vector search results matching your existing Laravel policies. Store API keys exclusively in environment variables, never in JavaScript bundles. On client portals handling sensitive legal documents alongside public products, I enforce strict tenant isolation at the vector collection level to prevent cross-tenant data exposure.

Yes, a 4-core 8GB RAM VPS running Ubuntu 24 can handle Meilisearch or Typesense with local Ollama embeddings for catalogs up to 30,000 products comfortably. Allocate at least 4GB RAM specifically to the vector engine. Monitor memory usage closely as vector indexes grow linearly with catalog size. For Nepali businesses avoiding international payment complications, self-hosting eliminates dependency on foreign SaaS billing. On shared EC2 infrastructure I manage for sister sites, this configuration handles multiple mid-size catalogs without issues, though larger deployments require dedicated resources.

Poorly implemented AI search destroys LCP and INP metrics due to slow embedding generation and large payload responses. Always cache embedding vectors in Redis with TTL matching your product update frequency. Return only essential fields from vector search results, fetching full product data from MySQL separately. Implement debounced search input with 300ms delay to reduce unnecessary API calls. Use streaming responses for autocomplete suggestions. On WooCommerce stores I have optimized, these patterns reduced search-related INP from over 500ms to under 150ms while maintaining semantic relevance.

Laravel Scout remains the foundation with official Meilisearch and Typesense drivers supporting vector search natively. Use pgvector driver for PostgreSQL-backed vector storage if already on Postgres. Spatie Laravel Data helps structure search result DTOs cleanly. For OpenAI integration, openai-php/laravel provides type-safe embedding generation. Avoid heavy abstraction layers that obscure what actually happens during search. In my experience, minimal package dependencies make debugging production search issues far easier when embeddings return unexpected results or performance degrades under load.

Track search-to-conversion rate, zero-result rate, and average session duration comparing AI search versus previous keyword search using A/B testing or feature flags. Log all search queries with result counts and click positions to identify gaps in semantic coverage. Monitor revenue per search session, not just conversion rate, as AI search may surface higher-value products. Use Laravel Telescope or custom logging to capture search latency and error rates. On eCommerce projects, I have observed conversion improvements ranging from fifteen to thirty percent, but only when combined with proper analytics validating actual business impact beyond novelty.

Common causes include poor product descriptions lacking semantic richness, incorrect chunking strategy splitting meaningful context, missing metadata filters allowing irrelevant categories to pollute results, and outdated embeddings not reflecting recent catalog changes. Audit your embedding input format to ensure it includes title, description, category, and attributes concatenated meaningfully. Verify filters are applied before vector similarity scoring, not after. Regenerate embeddings after significant catalog restructuring. On real client projects, I have found that improving source data quality yields better relevance gains than switching embedding models or tweaking similarity thresholds.

Most embedding models train primarily on English, causing degraded semantic understanding for Nepali product descriptions. Use multilingual models like bge-m3 or multilingual-e5-large that explicitly support Devanagari script. Consider translating key product attributes to English for embedding generation while displaying Nepali to users. Test extensively with actual Nepali search queries from your analytics, not translated English test cases. On Nepal-focused eCommerce platforms, I have found hybrid approaches combining Nepali keyword matching with English semantic vectors often outperform pure Nepali vector search due to training data limitations.

Start with tuned Laravel Scout using MySQL full-text search with synonym expansion and custom ranking rules before adding vectors. Elasticsearch or OpenSearch offer sophisticated text analysis without embedding complexity. Algolia provides managed search with learning-to-rank capabilities requiring minimal configuration. For small catalogs under 5,000 products, well-configured database search with proper indexing often suffices. In my engineering philosophy, prefer boring proven solutions until semantic search demonstrably solves a specific user problem. Many clients achieve adequate search relevance through data cleanup and filter improvements alone without introducing vector infrastructure overhead.

Share this article

Quick Contact Options
Choose how you want to connect me: