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

Zendsearch Laravel Package

zendframework/zendsearch

ZendSearch provides full-text search capabilities for PHP apps, offering indexing, querying, and analysis tools inspired by Lucene. Useful for adding fast, flexible search to your project with customizable analyzers, tokenizers, and query parsers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer (though note the package is archived; consider alternatives like elasticsearch/elasticsearch or opensearchphp/client for modern Laravel):

    composer require zendframework/zendsearch
    

    Note: If using Laravel, ensure compatibility with PHP 7.4+ via a legacy wrapper or fork.

  2. Basic Usage Initialize a ZendSearch\Lucene\Search instance:

    use ZendSearch\Lucene\Search\QueryParser;
    use ZendSearch\Lucene\Search\Query\Query;
    
    $indexPath = storage_path('app/lucene_index');
    $search = new \ZendSearch\Lucene\Search($indexPath);
    
  3. First Use Case: Indexing Add a document to the index:

    $doc = new \ZendSearch\Lucene\Document();
    $doc->addField(\ZendSearch\Lucene\Field\Text::unchecked('title', 'Laravel Assessment'));
    $doc->addField(\ZendSearch\Lucene\Field\Stored('content', 'Full content here...'));
    $search->addDocument($doc);
    
  4. First Query

    $query = new QueryParser();
    $hits = $search->find($query->parse('laravel'));
    foreach ($hits as $hit) {
        echo $hit->title; // Access stored fields
    }
    

Implementation Patterns

Workflows

  1. Indexing Strategy

    • Batch Indexing: Use Laravel’s Artisan::command to bulk-index data (e.g., during php artisan migrate or php artisan queue:work).
      public function handle() {
          $posts = Post::all();
          foreach ($posts as $post) {
              $doc = new \ZendSearch\Lucene\Document();
              $doc->addField(\ZendSearch\Lucene\Field\Text::unchecked('body', $post->body));
              $search->addDocument($doc);
          }
      }
      
    • Event-Based Indexing: Listen to eloquent.saved events to auto-index models:
      Post::saved(function ($post) {
          $search->addDocument($this->createDocument($post));
      });
      
  2. Query Patterns

    • Boolean Queries: Combine terms with AND, OR, NOT:
      $query = new \ZendSearch\Lucene\Search\Query\Boolean();
      $query->addSubQuery(new \ZendSearch\Lucene\Search\Query\Term('title', 'Laravel'), 'AND');
      $query->addSubQuery(new \ZendSearch\Lucene\Search\Query\Term('content', 'search'), 'AND');
      $hits = $search->find($query);
      
    • Pagination: Use Query::setLimit() and Query::setOffset():
      $query->setLimit(10);
      $query->setOffset(20);
      
  3. Integration with Laravel

    • Service Provider: Bind the search instance to the container:
      $this->app->singleton('search', function () {
          return new \ZendSearch\Lucene\Search(storage_path('app/lucene_index'));
      });
      
    • Eloquent Scopes: Create a custom scope for Lucene queries:
      public function scopeLuceneSearch($query, $searchTerm) {
          $hits = app('search')->find($searchTerm);
          return $query->whereIn('id', array_map(fn($hit) => $hit->id, $hits));
      }
      

Gotchas and Tips

Pitfalls

  1. Performance

    • Index Size: Lucene indexes grow with data. Monitor storage usage in storage/app/lucene_index.
    • Query Complexity: Avoid overly complex queries (e.g., nested Boolean queries) in high-traffic routes. Cache results or use Laravel’s cache()->remember().
  2. Field Types

    • Stored vs. Unstored Fields: Only Stored fields are retrievable. Use Field\Stored for data you need post-query:
      $doc->addField(\ZendSearch\Lucene\Field\Stored('id', $post->id));
      
    • Text vs. Keyword: Use Field\Text for full-text search and Field\Keyword for exact matches.
  3. Concurrency

    • Locking: Lucene isn’t thread-safe. Use Laravel’s Cache::lock() or Semaphore for concurrent writes:
      $lock = Cache::lock('lucene_index_lock', 10);
      if ($lock->get()) {
          $search->addDocument($doc);
          $lock->release();
      }
      
  4. Deprecation

    • Archived Package: Expect no updates. Plan for migration to Elasticsearch/OpenSearch if scaling beyond local development.

Debugging

  • Index Corruption: If the index crashes, delete storage/app/lucene_index and re-index. Backup first!
  • Query Debugging: Use var_dump($query->toString()) to inspect Lucene query syntax.
  • Field Mapping: Verify fields exist in the index with:
    $search->getFieldNames(); // List all indexed fields
    

Extension Points

  1. Custom Analyzers Override tokenization with a custom ZendSearch\Lucene\Analysis\Analyzer:

    $analyzer = new \ZendSearch\Lucene\Analysis\Analyzer\Standard\Standard();
    $field = new \ZendSearch\Lucene\Field\Text('custom_field', 'text', $analyzer);
    
  2. Custom Scoring Implement ZendSearch\Lucene\Search\Query\Query to modify relevance scoring:

    class CustomScoreQuery extends \ZendSearch\Lucene\Search\Query\Query {
        public function score($hit) {
            return $hit->getFieldValue('boost') * 2; // Custom logic
        }
    }
    
  3. Laravel Events Extend with events for indexing lifecycle:

    event(new LuceneIndexed($doc, $search));
    
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