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

Laravel Lucene Search Laravel Package

nqxcode/laravel-lucene-search

Laravel package that adds Lucene-powered full-text search to your app. Index Eloquent models and query them with fast, relevant results, plus helpers for managing indexes and integrating search into common Laravel workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation

    • Require the package via Composer:
      composer require nqxcode/laravel-lucene-search
      
    • Publish the config file (if needed):
      php artisan vendor:publish --provider="Nqxcode\LuceneSearch\LuceneServiceProvider"
      
    • Configure the config/lucene-search.php file with your Lucene index path and other settings.
  2. Basic Setup

    • Ensure you have a working Zend Framework 2 Lucene installation (this package wraps it).
    • Define a searchable() method in your Eloquent model to specify searchable fields:
      use Nqxcode\LuceneSearch\Searchable;
      
      class Post extends Model implements Searchable
      {
          public function searchable()
          {
              return [
                  'title' => 5, // Weight (higher = more important)
                  'body'  => 3,
              ];
          }
      }
      
  3. First Search Query

    • Use the search() method on the model:
      $results = Post::search('laravel')->get();
      
    • Or with pagination:
      $results = Post::search('laravel')->paginate(10);
      

Implementation Patterns

Common Workflows

  1. Basic Search

    • Full-text search across defined fields:
      $posts = Post::search('backend development')->get();
      
  2. Field-Specific Search

    • Search only in specific fields:
      $posts = Post::search('laravel', ['title'])->get();
      
  3. Boolean Queries

    • Combine terms with AND, OR, or NOT:
      $posts = Post::search('laravel AND framework')->get();
      $posts = Post::search('laravel NOT tutorial')->get();
      
  4. Fuzzy Search

    • Allow for minor typos:
      $posts = Post::search('laravel', [], ['fuzzy' => true])->get();
      
  5. Pagination & Sorting

    • Paginate results:
      $posts = Post::search('laravel')->paginate(15);
      
    • Sort by relevance (default) or other fields:
      $posts = Post::search('laravel')->orderBy('created_at', 'desc')->get();
      
  6. Integration with Eloquent Scopes

    • Create custom scopes for reusable search logic:
      class PostScope
      {
          public function scopePublished($query)
          {
              return $query->where('published', true);
          }
      }
      
      Then use it with search:
      $posts = Post::published()->search('laravel')->get();
      
  7. Real-Time Indexing

    • Manually trigger indexing for a model instance:
      $post = Post::find(1);
      $post->index(); // Add to Lucene index
      
    • Or use model events (creating, updating, deleting) to auto-index:
      protected static function boot()
      {
          parent::boot();
          static::created(function ($model) {
              $model->index();
          });
          static::updated(function ($model) {
              $model->index();
          });
          static::deleted(function ($model) {
              $model->unindex();
          });
      }
      
  8. Advanced Query Options

    • Use Lucene’s query syntax directly:
      $posts = Post::search('title:"Laravel" AND body:tutorial')->get();
      
    • Boost specific terms:
      $posts = Post::search('laravel^3 framework')->get();
      

Gotchas and Tips

Pitfalls & Debugging

  1. Index Path Permissions

    • Ensure the Lucene index directory is writable by the web server:
      chmod -R 775 storage/lucene-index
      
    • If using a custom path, verify it exists and is accessible.
  2. Case Sensitivity

    • Lucene is case-sensitive by default. Use lowercase in config or normalize fields in searchable():
      public function searchable()
      {
          return [
              'title' => 5,
              'body'  => ['field' => 'lowercase(body)'], // Normalize case
          ];
      }
      
  3. Performance with Large Datasets

    • Indexing many records can be slow. Batch updates:
      Post::chunk(100, function ($posts) {
          foreach ($posts as $post) {
              $post->index();
          }
      });
      
    • Consider running indexing via a queue job (e.g., Laravel Queues).
  4. Field Weighting

    • Higher weights (title: 5) amplify relevance but may skew results. Test with real data.
    • Avoid over-weighting fields that rarely contain search terms.
  5. Special Characters in Queries

    • Escape reserved characters (e.g., +, -, &&) in user input:
      $query = addcslashes($userInput, '+-!()[]{}:~*"&\|');
      $posts = Post::search($query)->get();
      
  6. Lucene Version Compatibility

    • The package relies on ZF2 Lucene (not the newer PHP Lucene port). Ensure your server has the correct PHP extension (php-zendframework2-lucene or similar).
  7. Debugging Queries

    • Enable Lucene query logging in config:
      'debug' => true,
      
    • Check Laravel logs for raw Lucene queries during searches.
  8. Concurrent Indexing Issues

    • If multiple processes index the same model, use a lock or queue to avoid duplicates:
      if (!$model->isIndexed()) {
          $model->index();
      }
      

Extension Points

  1. Custom Analyzers

    • Override the default analyzer (e.g., for stemming or stopwords):
      public function searchable()
      {
          return [
              'body' => [
                  'field' => 'body',
                  'analyzer' => 'custom_analyzer',
              ],
          ];
      }
      
    • Configure analyzers in config/lucene-search.php.
  2. Post-Processing Results

    • Extend the Nqxcode\LuceneSearch\SearchableTrait to add custom logic after retrieval:
      public function getResults()
      {
          $results = parent::getResults();
          // Add custom filtering or transformations
          return $results->filter(fn ($item) => $item->isVisible());
      }
      
  3. Multi-Model Search

    • Search across multiple models by querying each separately and merging results:
      $posts = Post::search($query)->get();
      $users = User::search($query)->get();
      $results = $posts->merge($users);
      
  4. Synonyms & Thesaurus

    • Use Lucene’s synonyms feature to improve search flexibility:
      // In config/lucene-search.php
      'synonyms' => [
          'php' => ['laravel', 'framework'],
      ],
      
  5. Integration with API Resources

    • Return search results in API responses with custom formatting:
      return new PostResourceCollection(Post::search($request->query('q'))->paginate());
      
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