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

Opensearch Laravel Package

pdphilip/opensearch

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation

    composer require pdphilip/opensearch
    

    Publish the config file:

    php artisan vendor:publish --provider="PdPhilip\OpenSearch\OpenSearchServiceProvider" --tag="config"
    
  2. Configure OpenSearch Connection Edit .env or config/opensearch.php:

    OPENSEARCH_HOST=http://localhost:9200
    OPENSEARCH_USERNAME=admin
    OPENSEARCH_PASSWORD=admin
    
  3. Basic Model Setup Extend your Eloquent model with PdPhilip\OpenSearch\Eloquent\Model:

    use PdPhilip\OpenSearch\Eloquent\Model;
    
    class Product extends Model
    {
        protected $connection = 'opensearch'; // Optional if default connection is set
        protected $index = 'products'; // Required: OpenSearch index name
        protected $primaryKey = 'id'; // Optional: Defaults to 'id'
    }
    
  4. First Query

    $products = Product::where('name', 'like', '%phone%')->get();
    
  5. Indexing Data

    php artisan opensearch:import App\Models\Product
    

    Or manually:

    $product = new Product();
    $product->save();
    

Where to Look First

  • Documentation: Check the GitLab repository for usage examples and API references.
  • Config File: config/opensearch.php for connection settings and default behaviors.
  • Artisan Commands: php artisan list to explore available commands like opensearch:import and opensearch:reindex.

Implementation Patterns

Common Workflows

1. Model Integration

  • Basic CRUD:

    // Create
    $product = new Product(['name' => 'Laptop', 'price' => 999]);
    $product->save();
    
    // Read
    $product = Product::find(1);
    $products = Product::all();
    
    // Update
    $product->price = 899;
    $product->save();
    
    // Delete
    $product->delete();
    
  • Querying:

    // Basic where
    $products = Product::where('price', '>', 500)->get();
    
    // Full-text search
    $products = Product::search('wireless headphones')->get();
    
    // Aggregations
    $results = Product::selectRaw('avg(price) as avg_price')->get();
    

2. Bulk Operations

  • Import Data:

    php artisan opensearch:import App\Models\Product --chunk=100
    

    Or programmatically:

    Product::import(); // Uses default chunk size
    Product::import(200); // Custom chunk size
    
  • Reindexing:

    php artisan opensearch:reindex App\Models\Product
    

3. Relationships

  • Define Relationships:
    class Category extends Model
    {
        public function products()
        {
            return $this->hasMany(Product::class);
        }
    }
    
    • Note: Relationships are not natively supported in OpenSearch like SQL databases. Use nested objects or denormalized data for complex queries.

4. Custom Mappings

  • Define mappings in your model:
    class Product extends Model
    {
        protected $mapping = [
            'properties' => [
                'name' => ['type' => 'text', 'analyzer' => 'english'],
                'price' => ['type' => 'float'],
                'tags' => ['type' => 'keyword']
            ]
        ];
    }
    
    • Apply mappings during model boot:
    protected static function boot()
    {
        parent::boot();
        static::booted(function () {
            if (!static::indexExists()) {
                static::createIndex();
            }
        });
    }
    

5. Event Handling

  • Listen for OpenSearch events:
    use PdPhilip\OpenSearch\Events\DocumentSaved;
    use Illuminate\Support\Facades\Event;
    
    Event::listen(DocumentSaved::class, function ($event) {
        logger()->info("Document saved: {$event->model->id}");
    });
    

Integration Tips

1. Hybrid Search (SQL + OpenSearch)

  • Use OpenSearch for full-text search and SQL for transactions:
    // Full-text search in OpenSearch
    $results = Product::search('wireless')->get();
    
    // Transactional data in SQL
    $product = Product::find(1);
    $product->price = $product->price - 100;
    $product->save(); // Saves to SQL
    

2. Caching Results

  • Cache frequent queries:
    $products = Cache::remember('featured_products', now()->addHours(1), function () {
        return Product::where('is_featured', true)->limit(10)->get();
    });
    

3. Pagination

  • Use Laravel's built-in pagination:
    $products = Product::paginate(15);
    

4. Testing

  • Use PdPhilip\OpenSearch\Testing\CreatesOpenSearchIndexes trait:
    use PdPhilip\OpenSearch\Testing\CreatesOpenSearchIndexes;
    use Tests\TestCase;
    
    class ProductTest extends TestCase
    {
        use CreatesOpenSearchIndexes;
    
        public function test_search()
        {
            $this->createIndex(Product::class);
            // Test logic here
        }
    }
    

Gotchas and Tips

Pitfalls

1. Index Management

  • Issue: Forgetting to create an index before querying.
    • Fix: Always check if the index exists or use createIndex() in model boot:
      protected static function boot()
      {
          parent::boot();
          static::booted(function () {
              if (!static::indexExists()) {
                  static::createIndex();
              }
          });
      }
      

2. Data Type Mismatches

  • Issue: OpenSearch may silently fail or return unexpected results if data types don’t match the mapping (e.g., storing a string in a float field).
    • Fix: Define explicit mappings in your model or use casts:
      protected $casts = [
          'price' => 'float',
          'is_active' => 'boolean',
      ];
      

3. Bulk Import Failures

  • Issue: Bulk imports may fail silently or partially due to network issues or invalid data.
    • Fix: Use smaller chunk sizes and validate data before importing:
      php artisan opensearch:import App\Models\Product --chunk=50
      
    • Log errors during import:
      Product::import(50, true); // Enable logging
      

4. Relationship Limitations

  • Issue: OpenSearch doesn’t support SQL-like joins or relationships natively.
    • Fix: Denormalize data or use nested objects:
      // Example: Store category as nested object
      $product = new Product([
          'name' => 'Laptop',
          'category' => ['id' => 1, 'name' => 'Electronics']
      ]);
      

5. Connection Timeouts

  • Issue: Slow responses or timeouts when connecting to OpenSearch.
    • Fix: Adjust timeout settings in config/opensearch.php:
      'timeout' => 30, // seconds
      'retries' => 3,
      

Debugging Tips

1. Enable Debugging

  • Enable query logging in config/opensearch.php:
    'debug' => env('OPENSEARCH_DEBUG', false),
    
    • Check logs in storage/logs/laravel.log for raw OpenSearch queries.

2. Raw OpenSearch Queries

  • Use toSearch() to inspect the generated query:
    $query = Product::where('name', 'like', '%phone%')->toSearch();
    logger()->info($query);
    

3. Index Existence Checks

  • Verify index existence manually:
    if (!Product::indexExists()) {
        logger()->error('Index does not exist!');
    }
    

4. Mapping Validation

  • Validate mappings before importing:
    Product::validateMapping();
    

Extension Points

1. Custom Query Builders

  • Extend the query builder for domain-specific logic:
    namespace App\OpenSearch\Query;
    
    use PdPhilip\OpenSearch\Builder;
    
    class ProductQueryBuilder extends Builder
    {
        public function inStock()
        {
            return $this->where('stock', '>', 0);
        }
    }
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope