Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Elasticsearch Store Laravel Package

symfony/ai-elasticsearch-store

Elasticsearch Store integrates Elasticsearch as a vector store for Symfony AI Store. It supports kNN vector search using dense_vector fields, enabling similarity search and retrieval over embeddings with Elasticsearch-backed indexing and querying.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require symfony/ai-elasticsearch-store
    
  2. Configure Elasticsearch Client Add the Elasticsearch client to your Laravel service container (e.g., in config/services.php or a custom config file):

    'elasticsearch' => [
        'hosts' => [
            ['host' => 'localhost', 'port' => 9200],
        ],
        'index' => 'vector_store', // Your Elasticsearch index name
    ],
    
  3. Register the Store Bind the Elasticsearch store to Symfony AI’s StoreInterface in your service container (e.g., AppServiceProvider):

    use Symfony\Component\AI\Store\StoreInterface;
    use Symfony\Component\AI\ElasticsearchStore\ElasticsearchStore;
    
    public function register()
    {
        $this->app->singleton(StoreInterface::class, function ($app) {
            $client = new \Elasticsearch\Client($app['config']['elasticsearch']);
            return new ElasticsearchStore($client, $app['config']['elasticsearch']['index']);
        });
    }
    
  4. First Use Case: Storing and Retrieving Embeddings

    use Symfony\Component\AI\Store\StoreInterface;
    
    public function storeAndRetrieve(StoreInterface $store)
    {
        // Store an embedding with metadata
        $store->add('doc1', [0.1, 0.2, 0.3], ['title' => 'Laravel AI', 'category' => 'framework']);
    
        // Retrieve similar embeddings
        $results = $store->nearest([0.15, 0.25, 0.35], 3);
    
        // Filtered nearest search
        $filteredResults = $store->nearest([0.15, 0.25, 0.35], 3, [
            'filter' => ['term' => ['category' => 'framework']],
        ]);
    }
    
  5. Verify Elasticsearch Index Ensure your Elasticsearch index has a dense_vector field. Example mapping:

    PUT /vector_store
    {
        "mappings": {
            "properties": {
                "embedding": {
                    "type": "dense_vector",
                    "dims": 3 // Adjust to your embedding dimension
                }
            }
        }
    }
    

Implementation Patterns

Core Workflows

1. Vector Storage and Retrieval

  • Add Embeddings with Metadata
    $store->add('unique_id', $embeddingArray, ['metadata' => 'value']);
    
  • Bulk Insert
    $store->addAll([
        'id1' => [$embedding1, ['category' => 'tech']],
        'id2' => [$embedding2, ['category' => 'science']],
    ]);
    
  • Nearest Neighbor Search
    $results = $store->nearest($queryEmbedding, $limit = 5, [
        'filter' => ['term' => ['category' => 'tech']],
        'knn' => true, // Enable approximate search for performance
    ]);
    
    Returns an array of ['id' => string, 'embedding' => array, 'metadata' => array].

2. Hybrid Search (Keyword + Vector)

Combine Elasticsearch’s query DSL with vector similarity:

$results = $store->nearest($queryEmbedding, 5, [
    'filter' => [
        'bool' => [
            'must' => [
                'term' => ['category' => 'books'],
                'range' => ['price' => ['gte' => 10]],
            ],
        ],
    ],
]);

3. Dynamic Updates and Deletion

  • Remove by ID
    $store->remove('doc1');
    
  • Bulk Removal
    $store->removeAll(['doc1', 'doc2']);
    

4. RAG Pipeline Integration

public function ragPipeline(StoreInterface $store, LLM $llm)
{
    $queryEmbedding = $llm->embed("What is Laravel AI?");
    $relevantDocs = $store->nearest($queryEmbedding, 3);
    $context = implode("\n\n---\n\n", array_map(
        fn($doc) => "Title: {$doc['metadata']['title']}\nContent: {$doc['metadata']['content']}",
        $relevantDocs
    ));
    return $llm->complete("Answer the question using only the context below:\n\n$context\n\nQuestion: What is Laravel AI?");
}

Integration Tips

Laravel-Specific Adaptations

  1. Service Container Binding Extend the store binding to include Laravel-specific features (e.g., caching):

    $this->app->singleton(StoreInterface::class, function ($app) {
        $client = new \Elasticsearch\Client($app['config']['elasticsearch']);
        $store = new ElasticsearchStore($client, $app['config']['elasticsearch']['index']);
    
        // Cache results for 5 minutes
        Cache::remember("vector_store_{$query}", 300, function() use ($store, $query) {
            return $store->nearest($query['embedding'], $query['limit'], $query['filter']);
        });
    
        return $store;
    });
    
  2. Queue Background Jobs Offload bulk operations to queues:

    public function handleBulkInsert(BulkInsertRequest $request)
    {
        BulkInsertJob::dispatch($request->embeddings);
    }
    
    // BulkInsertJob.php
    public function handle()
    {
        $store = app(StoreInterface::class);
        $store->addAll($this->embeddings);
    }
    
  3. Event Listeners for Index Management Listen to model events to sync embeddings:

    public function boot()
    {
        Document::saved(function ($document) {
            $store = app(StoreInterface::class);
            $embedding = $this->generateEmbedding($document->content);
            $store->add($document->id, $embedding, $document->toArray());
        });
    }
    

Elasticsearch Optimization

  1. Index Configuration Define a custom index with optimized settings:

    $client->indices()->create([
        'index' => 'vector_store',
        'body' => [
            'mappings' => [
                'properties' => [
                    'embedding' => [
                        'type' => 'dense_vector',
                        'dims' => 384, // Adjust to your embedding dimension
                    ],
                    'metadata' => [
                        'properties' => [
                            'title' => ['type' => 'text'],
                            'category' => ['type' => 'keyword'],
                        ],
                    ],
                ],
            ],
            'settings' => [
                'index' => [
                    'knn' => true,
                    'knn.algo_param.ef_search' => 100, // Optimize for search performance
                ],
            ],
        ],
    ]);
    
  2. Sharding and Replication For large datasets, configure shards and replicas:

    $client->indices()->putSettings([
        'index' => 'vector_store',
        'body' => [
            'index.number_of_shards' => 3,
            'index.number_of_replicas' => 1,
        ],
    ]);
    
  3. Alias for Zero-Downtime Updates Use aliases to switch indices without downtime:

    $client->indices()->createAlias(['index' => 'vector_store_v2', 'name' => 'vector_store']);
    

Gotchas and Tips

Pitfalls

  1. Index Mapping Mismatches

    • Issue: Forgetting to define the dense_vector field or using incorrect dimensions causes failures.
    • Fix: Verify mappings with:
      $client->indices()->getMapping(['index' => 'vector_store']);
      
    • Tip: Use a script to validate embeddings match the dims setting.
  2. Filter Syntax Errors

    • Issue: Elasticsearch’s query DSL is strict. Incorrect filter syntax (e.g., term vs match) returns no results.
    • Fix: Test filters in Kibana Dev Tools first:
      GET /vector_store/_search
      {
        "query": {
          "bool": {
            "filter": {
              "term": { "category.keyword": "tech" }
            }
          }
        }
      }
      
    • Tip: Use keyword for exact matches (e.g., category.keyword) and text for full-text.
  3. Performance Bottlenecks

    • Issue: Slow queries due to unoptimized indices or large ef_search values.
    • Fix:
      • Monitor query performance with Elasticsearch’s profiling:
        $params = [
            'body' => [
        
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky