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

Ramen Elastic Query Laravel Package

hungneox/ramen-elastic-query

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require hungneox/ramen-elastic-query
    

    Register the service provider in bootstrap/app.php:

    $app->register(Neox\Ramen\Elastic\ElasticQueryServiceProvider::class);
    
  2. First Query: Use the facade (ES) or container binding (app(Builder::class)) to query an index:

    $result = ES::use('content')->from('article')->find('TIYKtQX', '_id', ['id', 'title']);
    
  3. Key Files:

    • config/elasticsearch.php (if present, check for custom configurations).
    • app/Providers/ElasticQueryServiceProvider.php (for service binding overrides).

First Use Case

Fetch a document by ID:

$article = ES::use('content')->from('article')->find('TIYKtQX', '_id', ['id', 'title']);

Search with full-text matching:

$results = ES::use('content')
    ->from('article')
    ->where('title', 'like', 'Laravel')
    ->get();

Implementation Patterns

Core Workflows

  1. Query Chaining: Chain methods for readability and maintainability:

    $results = ES::use('content')
        ->from('article')
        ->select('id', 'title')
        ->where('published', '=', true)
        ->orderBy('created_at', 'desc')
        ->limit(10)
        ->get();
    
  2. Dynamic Index/Collection Handling: Use the use() method to switch between Elasticsearch collections (e.g., content, analytics):

    // Switch collections dynamically
    $collection = request()->input('collection');
    $results = ES::use($collection)->from('type')->get();
    
  3. Pagination: Leverage limit() and offset() for pagination:

    $results = ES::use('content')
        ->from('article')
        ->limit(20)
        ->offset(0)
        ->get();
    
  4. Bulk Operations: Use delete() for bulk deletions (e.g., soft deletes via _id):

    $ids = [1, 2, 3];
    foreach ($ids as $id) {
        ES::use('content')->from('article')->delete($id);
    }
    

Integration Tips

  • Laravel Eloquent Integration: Use the package alongside Eloquent for hybrid queries:

    $user = User::whereHas('articles', function ($query) {
        $query->where('title', 'like', '%Laravel%');
    })->first();
    

    Then fetch Elasticsearch results for the same data:

    $esResults = ES::use('content')->from('article')->where('title', 'like', '%Laravel%')->get();
    
  • Caching Results: Cache frequent queries to reduce Elasticsearch load:

    $results = Cache::remember("es_articles_{$searchTerm}", now()->addHours(1), function () use ($searchTerm) {
        return ES::use('content')->from('article')->where('title', 'like', $searchTerm)->get();
    });
    
  • Error Handling: Wrap queries in try-catch blocks to handle Elasticsearch exceptions gracefully:

    try {
        $results = ES::use('content')->from('article')->find($id, '_id');
    } catch (\Exception $e) {
        Log::error("Elasticsearch error: " . $e->getMessage());
        return response()->json(['error' => 'Failed to fetch data'], 500);
    }
    

Gotchas and Tips

Pitfalls

  1. Collection vs. Index Confusion:

    • The use() method sets the collection (e.g., content), while from() sets the index/type (e.g., article).
    • Mixing these up will result in NotFoundException errors.
    • Fix: Double-check the use() and from() methods in your queries.
  2. Full-Text Search Quirks:

    • The like operator in where() uses Elasticsearch's match query under the hood. For advanced full-text search, consider using raw queries:
      $result = ES::use('content')->from('article')->rawQuery([
          'query' => [
              'match_phrase' => ['title' => 'Laravel Elasticsearch']
          ]
      ])->get();
      
  3. Missing select():

    • Omitting select() returns all fields, which can be inefficient for large documents.
    • Tip: Always explicitly define fields to fetch:
      ->select('id', 'title', 'created_at') // Explicit fields
      
  4. Facade vs. Container Binding:

    • The facade (ES) is convenient but may not support dependency injection. For testing, prefer container binding:
      $builder = app(Neox\Ramen\Elastic\Builder::class);
      
  5. Bulk API Limitations:

    • The delete() method processes deletions one-by-one. For bulk deletions, use Elasticsearch's Bulk API directly:
      $client = app('elasticsearch');
      $client->bulk(['body' => $bulkPayload]);
      

Debugging

  1. Raw Query Inspection: Use toQuery() to inspect the generated Elasticsearch query:

    $query = ES::use('content')->from('article')->where('title', 'like', 'Laravel')->toQuery();
    dd($query); // Debug the raw query
    
  2. Logging: Enable Elasticsearch client logging in config/elasticsearch.php:

    'log' => [
        'enabled' => true,
        'level' => 'debug',
    ],
    
  3. Common Errors:

    • NotFoundException: Verify the collection/index exists in Elasticsearch.
    • InvalidArgumentException: Check for typos in field names or operators (e.g., = vs. ==).
    • ConnectionException: Ensure Elasticsearch is running and the client is configured correctly.

Extension Points

  1. Custom Query Builders: Extend the Builder class to add domain-specific methods:

    class ArticleQueryBuilder extends \Neox\Ramen\Elastic\Builder
    {
        public function published()
        {
            return $this->where('published', '=', true);
        }
    }
    

    Bind it in ElasticQueryServiceProvider:

    $this->app->bind('article.query', function () {
        return new ArticleQueryBuilder();
    });
    
  2. Raw Query Support: Use rawQuery() for complex queries not supported by the fluent interface:

    $result = ES::use('content')->from('article')->rawQuery([
        'query' => [
            'bool' => [
                'must' => [
                    ['match' => ['title' => 'Laravel']],
                    ['range' => ['created_at' => ['gte' => 'now-1y']]]
                ]
            ]
        ]
    ])->get();
    
  3. Event Listeners: Listen for query events (e.g., QueryExecuted) to log or modify queries:

    Event::listen('Neox\Ramen\Elastic\Events\QueryExecuted', function ($event) {
        Log::debug('Executed Elasticsearch query:', $event->query);
    });
    
  4. Testing: Use mocks for Elasticsearch in tests:

    $mock = Mockery::mock('overload', 'elasticsearch');
    $mock->shouldReceive('get')->andReturn(['hits' => ['hits' => []]]);
    
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.
facebook/capi-param-builder-php
babelqueue/symfony
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