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

Seal Redisearch Adapter Laravel Package

cmsig/seal-redisearch-adapter

RediSearch adapter for the SEAL search engine. Index and query documents in a Redis Stack instance using RediSearch + RedisJSON. Supports ext-redis/ext-json and DSN-based configuration; note: no GeoBoundingBox or HIGHLIGHT support.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies:

    composer require cmsig/seal cmsig/seal-redisearch-adapter
    

    Ensure ext-redis and ext-json PHP extensions are enabled.

  2. Configure Redis:

    • Install Redis with RediSearch and RedisJSON modules enabled.
    • Verify modules are loaded:
      redis-cli MODULE LIST
      
    • Expected output includes redisearch and redisjson.
  3. Basic Setup in Laravel:

    • Create a Redis connection in config/database.php:
      'connections' => [
          'redis' => [
              'driver' => 'redis',
              'host' => env('REDIS_HOST', '127.0.0.1'),
              'password' => env('REDIS_PASSWORD', null),
              'port' => env('REDIS_PORT', 6379),
          ],
      ],
      
    • Define a schema (e.g., app/Search/Schemas/ProductSchema.php):
      return [
          'fields' => [
              'id' => ['type' => 'TAG'],
              'name' => ['type' => 'TEXT', 'SORTABLE' => true],
              'price' => ['type' => 'NUMERIC'],
              'category' => ['type' => 'TAG'],
          ],
      ];
      
  4. Initialize Engine:

    • In a service provider (e.g., AppServiceProvider):
      use CmsIg\Seal\Engine;
      use CmsIg\Seal\Adapter\RediSearch\RediSearchAdapter;
      use Illuminate\Support\Facades\Redis;
      
      public function register()
      {
          $schema = include __DIR__.'/../Search/Schemas/ProductSchema.php';
          $this->app->singleton('search.engine', function () {
              return new Engine(new RediSearchAdapter(Redis::connection()), $schema);
          });
      }
      
  5. First Query:

    • Use the engine in a controller or service:
      $engine = app('search.engine');
      $results = $engine->search('query', ['limit' => 10]);
      

Implementation Patterns

Usage Patterns

1. Indexing Data

  • Bulk Indexing: Use Laravel’s queues to offload indexing for large datasets:

    use Illuminate\Support\Facades\Bus;
    
    Bus::dispatch(new IndexProductsJob($products));
    
    // IndexProductsJob.php
    public function handle()
    {
        $engine = app('search.engine');
        foreach ($this->products as $product) {
            $engine->index($product->id, $product->toSearchArray());
        }
    }
    
  • Model Observers: Auto-index models on update:

    // ProductObserver.php
    public function saved(Product $product)
    {
        $engine = app('search.engine');
        $engine->index($product->id, $product->toSearchArray());
    }
    

2. Querying Data

  • Basic Search:

    $results = $engine->search('laptop', [
        'limit' => 10,
        'offset' => 0,
        'sortBy' => 'price',
    ]);
    
  • Filtered Search: Use RediSearch’s FILTER syntax via SEAL’s query builder:

    $results = $engine->search('laptop', [
        'filter' => 'category:{electronics}',
    ]);
    
  • Aggregations:

    $aggregations = $engine->aggregate('category', [
        'groupBy' => 'category',
        'reduce' => 'COUNT',
    ]);
    

3. Schema Management

  • Dynamic Schemas: Load schemas dynamically based on environment:

    $schema = config('search.schemas.'.config('app.env'));
    $engine = new Engine(new RediSearchAdapter(Redis::connection()), $schema);
    
  • Partial Updates: Update specific fields without reindexing:

    $engine->update($productId, ['price' => 999.99]);
    

4. Laravel Integration

  • Service Container Binding: Bind the engine to an interface for easier mocking in tests:

    $this->app->bind(
        SearchEngineInterface::class,
        function () {
            return new Engine(new RediSearchAdapter(Redis::connection()), $schema);
        }
    );
    
  • API Resources: Transform search results into API responses:

    // ProductSearchResource.php
    public function toArray($request, Product $product)
    {
        return [
            'id' => $product->id,
            'name' => $product->name,
            'price' => $product->price,
        ];
    }
    
  • Blade Directives: Create a Blade directive for search forms:

    Blade::directive('searchForm', function ($expression) {
        return "<?php echo $expression; ?>";
    });
    
    @searchForm('<form action="/search" method="GET">
        <input type="text" name="q" value="{{ request('q') }}">
        <button type="submit">Search</button>
    </form>')
    

Workflows

1. Search Pipeline

  • Request Handling:

    // routes/web.php
    Route::get('/search', function () {
        $query = request('q');
        $engine = app('search.engine');
        $results = $engine->search($query, [
            'limit' => 20,
            'withPayload' => true,
        ]);
        return view('search.results', compact('results'));
    });
    
  • Caching Results: Cache frequent queries to reduce Redis load:

    $cacheKey = "search:{$query}:".implode(',', $filters);
    return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($engine, $query, $filters) {
        return $engine->search($query, $filters);
    });
    

2. Data Synchronization

  • Event-Driven Indexing: Use Laravel events to keep search index in sync:

    // ProductCreated.php
    public function handle()
    {
        $engine = app('search.engine');
        $engine->index($this->product->id, $this->product->toSearchArray());
    }
    
  • Periodic Reindexing: Schedule a Laravel command to reindex stale data:

    php artisan schedule:run
    
    // ReindexCommand.php
    public function handle()
    {
        $engine = app('search.engine');
        $engine->reindex(Product::all()->pluck('id')->toArray());
    }
    

3. Testing

  • Unit Tests: Mock the Redis connection for isolated tests:

    $mockRedis = Mockery::mock(Redis::class);
    $mockRedis->shouldReceive('search')->andReturn(['result']);
    $engine = new Engine(new RediSearchAdapter($mockRedis), $schema);
    
  • Feature Tests: Test search endpoints with real data:

    public function test_search_endpoint()
    {
        $response = $this->get('/search?q=laptop');
        $response->assertStatus(200);
        $response->assertSee('Laptop Pro');
    }
    

Integration Tips

  1. Redis Connection Pooling:

    • Use Laravel’s Redis connection with connection names for multi-environment setups:
      $engine = new Engine(new RediSearchAdapter(Redis::connection('redis-cache')), $schema);
      
  2. Schema Validation:

    • Validate schemas against RediSearch’s field types to avoid runtime errors:
      $validTypes = ['TEXT', 'TAG', 'NUMERIC', 'GEO', 'HASH'];
      foreach ($schema['fields'] as $field) {
          assert(in_array($field['type'], $validTypes), "Invalid field type: {$field['type']}");
      }
      
  3. Error Handling:

    • Wrap engine calls in try-catch blocks to handle Redis failures gracefully:
      try {
          $results = $engine->search($query);
      } catch (RedisException $e) {
          Log::error("Search failed: {$e->getMessage()}");
          return back()->withError('Search service unavailable');
      }
      
  4. Performance Tuning:

    • Optimize RediSearch indexes with INDEX definitions:
      $engine->createIndex([
          'index' => 'products',
          'fields' => [
              'name' => ['TYPE' => 'TEXT', 'WEIGHT' => 10],
              'description' => ['TYPE' => 'TEXT', 'WEIGHT' => 5],
          ],
      ]);
      
  5. Laravel Scout Alternative:

    • Replace Scout’s default
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.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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