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 Searchable Laravel Package

mozex/laravel-searchable

Add a Searchable trait to any Eloquent model to search multiple columns and related data (relations, morphs, even cross-database) via a single ->search() call. Works with Laravel Scout and includes optional Filament table/global search integration.

View on GitHub
Deep Wiki
Context7
## Technical Evaluation

### **Architecture Fit**
- **Strengths**:
  - **Eloquent Integration**: Seamlessly integrates with Laravel's Eloquent ORM, leveraging existing query builder patterns without requiring external search engines (e.g., Scout/Algolia). Ideal for applications where SQL-based search suffices or where full-text search engines are overkill.
  - **Multi-Column/Morph Support**: Enables complex search queries across direct columns, relations (BelongsTo/HasMany), polymorphic relations, and even cross-database relations. This aligns well with Laravel applications requiring hierarchical or polymorphic data traversal (e.g., comments on posts/videos, multi-tenant systems).
  - **Filament Compatibility**: Native support for Filament’s admin panel (global search, table search) reduces frontend-backend friction, accelerating MVP development for admin interfaces.
  - **Lightweight**: No additional infrastructure (e.g., Elasticsearch) or config files; zero migration overhead. Fits microservices or serverless architectures where database operations are preferred.

- **Weaknesses**:
  - **Performance Limitations**: Relies on `LIKE '%term%'` queries, which are inefficient for large datasets (>1M rows) due to full-table scans. Indexes on search columns won’t help, and correlated subqueries for relations add overhead.
  - **No Full-Text Indexing**: Lacks advanced features like fuzzy matching, stemming, or relevance scoring (unlike Scout/Meilisearch). Case sensitivity is database-dependent (e.g., MySQL collations).
  - **Cross-Database Workarounds**: External relation searches use `WHERE IN` with a hard cap (50 IDs by default), risking incomplete results for broad queries. Requires manual tuning (`externalLimit`).
  - **Scout Conflict**: Potential naming collisions with Laravel Scout’s `search()` method, necessitating trait aliasing or manual method invocation.

### **Integration Feasibility**
- **Prerequisites**:
  - **Laravel 10+** (PHP 8.2+): Compatible with modern Laravel stacks but may require minor adjustments for legacy projects (e.g., custom query builders).
  - **Database Support**: Tested on MySQL, PostgreSQL, SQLite. Cross-database relations require additional configuration (e.g., connection aliases).
  - **Filament (Optional)**: If using Filament, ensures zero-config global/table search. Non-Filament projects can ignore this feature.

- **Dependencies**:
  - **Core**: Zero external dependencies beyond Laravel/Eloquent.
  - **Filament**: Requires Filament v3+ for admin integration.
  - **Scout**: Coexists but requires explicit method aliasing to avoid conflicts.

- **Customization**:
  - **Dynamic Columns**: Supports runtime column filtering (`in`, `include`, `except`), enabling flexible search logic per query.
  - **Query Chaining**: Works alongside Eloquent’s `where()`, `orderBy()`, etc., preserving existing query patterns.

### **Technical Risk**
- **High-Risk Areas**:
  - **Performance at Scale**: Unsuitable for high-volume search (>100K rows/table) without optimizations (e.g., `pg_trgm` on PostgreSQL, Scout fallback).
  - **Cross-Database Queries**: External relation limits (50 IDs) may truncate results. Requires testing with real-world data volumes.
  - **Case Sensitivity**: Behavior varies by database (e.g., SQLite’s ASCII-only `LIKE`). May need collation adjustments.
  - **Trait Conflicts**: Existing `scopeSearch` methods (e.g., custom builders) require manual resolution via `applySearch()` or trait aliasing.

- **Mitigation Strategies**:
  - **Hybrid Approach**: Use Scout for global search + this package for admin/table searches (e.g., Filament).
  - **Fallback Logic**: Implement a `scoutFallback()` method to switch to Scout when query performance degrades (e.g., based on row count).
  - **Testing**: Validate cross-database relations with production-like data volumes and edge cases (e.g., empty results, large `IN` clauses).
  - **Documentation**: Clearly outline trait aliasing steps for Scout/Filament integrations in the team’s Laravel style guide.

### **Key Questions**
1. **Search Volume/Scale**:
   - How many rows will be searched per table? If >100K, is Scout/Meilisearch a viable fallback?
   - Are there specific performance benchmarks (e.g., max acceptable query time)?

2. **Data Complexity**:
   - Will searches frequently traverse polymorphic relations or cross-database links? If so, test `externalLimit` thresholds.
   - Are there case-sensitivity requirements (e.g., exact matches for usernames)?

3. **Integration Constraints**:
   - Does the project use custom Eloquent builders (e.g., Corcel) or parent model `scopeSearch` methods? If yes, plan for `applySearch()` usage.
   - Is Filament used? If not, can the package’s Filament features be ignored?

4. **Maintenance**:
   - Who will handle trait conflicts (e.g., Scout aliasing) during onboarding? Should this be automated via a base model?
   - Are there plans to extend search functionality (e.g., fuzzy matching)? If so, Scout may be a better long-term fit.

5. **Observability**:
   - How will slow queries be monitored? Consider logging `LIKE` query execution times.
   - Are there plans to add query caching for frequent searches?

---
## Integration Approach

### **Stack Fit**
- **Ideal Use Cases**:
  - **Admin Interfaces**: Filament-powered dashboards with global/table search (e.g., e-commerce product catalogs, CMS content).
  - **Internal Tools**: Applications where search is secondary to CRUD (e.g., support ticket systems, analytics dashboards).
  - **Polyglot Persistence**: Systems with cross-database relations (e.g., SaaS multi-tenancy with separate DBs per tenant).
  - **MVP Development**: Rapid prototyping where full-text search engines are premature.

- **Poor Fit**:
  - **High-Traffic Public Faces**: E-commerce product search, job boards, or any user-facing search with >10K queries/day.
  - **Advanced Search Features**: Need for fuzzy matching, synonyms, or relevance ranking (e.g., "Did you mean?" suggestions).
  - **Legacy Systems**: Projects with deeply customized Eloquent builders or trait conflicts that can’t be resolved.

### **Migration Path**
1. **Assessment Phase**:
   - Audit existing search implementations (e.g., custom `LIKE` queries, Scout).
   - Identify models requiring search functionality and their relation structures.

2. **Pilot Integration**:
   - Start with a non-critical model (e.g., `Comment` or `Tag`) to test:
     - Basic column search (`searchableColumns`).
     - Relation traversal (e.g., `author.name`).
     - Filament integration (if applicable).
   - Measure query performance (e.g., `EXPLAIN ANALYZE`) and compare to existing solutions.

3. **Incremental Rollout**:
   - **Phase 1**: Replace simple `LIKE` queries with the package’s trait (e.g., `Post::where('title', 'LIKE', '%term%')` → `Post::search('term')`).
   - **Phase 2**: Add relation/morph support for complex queries.
   - **Phase 3**: Integrate with Filament (global/searchable columns).
   - **Phase 4**: Implement Scout fallback for slow queries (e.g., via middleware or a `Searchable` interface).

4. **Conflict Resolution**:
   - For Scout conflicts, create a base model with trait aliasing:
     ```php
     abstract class SearchableModel extends Model
     {
         use Mozex\Searchable\Searchable {
             scopeSearch as scopeDatabaseSearch;
         }
     }
     ```
   - For custom builders, override `search()` to delegate to `applySearch()`:
     ```php
     class ProductBuilder extends Builder
     {
         public function search($term, array $options = [])
         {
             return $this->getModel()->applySearch($this, $term, ...$options);
         }
     }
     ```

### **Compatibility**
- **Laravel Versions**: Officially supports Laravel 10+. Test compatibility with Laravel 11 if using beta/RC.
- **Database Compatibility**:
  - **MySQL/PostgreSQL**: Fully supported. PostgreSQL benefits from `pg_trgm` for `LIKE` performance.
  - **SQLite**: Case-insensitive only for ASCII; may need collation adjustments for non-ASCII data.
  - **SQL Server**: Untested; may require custom query adjustments.
- **Relation Types**:
  - **BelongsTo/HasMany**: Native support.
  - **Polymorphic**: Requires explicit morph map configuration.
  - **ManyToMany**: Supported via relation dot notation (e.g., `tags.name`).
  - **External DBs**: Works but with `WHERE IN` limits (configurable via `externalLimit`).

### **Sequencing**
1. **Core Integration**:
   - Add `Searchable` trait to models and define `searchableColumns()`.
   - Test basic searches (`Model::search('term')`).

2. **Relation Support**:
   - Implement relation/morph searches (e.g., `author.name`, `commentable:post.title`).
   - Validate cross-database queries with `externalLimit` tuning.

3. **Query Optimization**:
   - Add indexes to filtered columns (e
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