Convert Figma logo to code with AI

nicolaslopezj logosearchable

A php trait to search laravel models

2,012
291
2,012
105

Top Related Projects

1,539

Laravel Scout provides a driver based solution to searching your Eloquent models.

Pragmatically search through models and other sources

Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch

Easy creation of slugs for your Eloquent models in Laravel

Add tags and taggable behaviour to your Laravel app

Quick Overview

Searchable is a Laravel package that provides a trait to make Eloquent models searchable. It allows you to easily add search functionality to your Laravel applications by defining searchable attributes and relationships on your models.

Pros

  • Easy to implement and use with existing Eloquent models
  • Supports searching through relationships and nested attributes
  • Customizable search algorithm with weight assignments
  • Integrates well with Laravel's query builder

Cons

  • Limited to Laravel applications only
  • May require additional configuration for complex search scenarios
  • Performance might be affected for large datasets or complex queries
  • Documentation could be more comprehensive

Code Examples

  1. Basic usage:
use Nicolaslopezj\Searchable\SearchableTrait;

class User extends Model
{
    use SearchableTrait;

    protected $searchable = [
        'columns' => [
            'users.name' => 10,
            'users.email' => 5,
        ],
    ];
}

// Perform a search
$users = User::search('John Doe')->get();
  1. Searching through relationships:
class Post extends Model
{
    use SearchableTrait;

    protected $searchable = [
        'columns' => [
            'posts.title' => 10,
            'posts.content' => 5,
            'author.name' => 2,
        ],
        'joins' => [
            'author' => ['users.id', 'posts.author_id'],
        ],
    ];
}

// Search posts including author information
$posts = Post::search('Laravel tips')->get();
  1. Custom search query:
$users = User::search('John')
    ->orWhere('role', 'admin')
    ->orderBy('created_at', 'desc')
    ->paginate(20);

Getting Started

  1. Install the package via Composer:

    composer require nicolaslopezj/searchable
    
  2. Add the SearchableTrait to your model and define searchable attributes:

    use Nicolaslopezj\Searchable\SearchableTrait;
    
    class YourModel extends Model
    {
        use SearchableTrait;
    
        protected $searchable = [
            'columns' => [
                'column_name' => 10,
                'another_column' => 5,
            ],
        ];
    }
    
  3. Use the search() method to perform searches:

    $results = YourModel::search('query string')->get();
    

Competitor Comparisons

1,539

Laravel Scout provides a driver based solution to searching your Eloquent models.

Pros of Scout

  • Seamless integration with Laravel's Eloquent ORM
  • Supports multiple search engines (Algolia, MeiliSearch, Database)
  • Offers queue-based indexing for improved performance

Cons of Scout

  • Requires additional setup for external search engines
  • May have a steeper learning curve for beginners
  • Limited customization options compared to Searchable

Code Comparison

Searchable:

class User extends Model
{
    use Searchable;

    protected $searchable = [
        'columns' => [
            'users.name' => 10,
            'users.email' => 5,
        ],
    ];
}

Scout:

class User extends Model
{
    use Searchable;

    public function toSearchableArray()
    {
        return [
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

Both packages offer search functionality for Laravel applications, but they differ in their approach and features. Searchable provides a simpler setup with built-in database searching, while Scout offers more flexibility and integration with external search engines. The choice between the two depends on the specific requirements of your project and the desired level of customization and scalability.

Pragmatically search through models and other sources

Pros of laravel-searchable

  • Specifically designed for Laravel, offering seamless integration
  • Supports searching through multiple models simultaneously
  • Allows for custom search algorithms and weighting of results

Cons of laravel-searchable

  • Limited to Laravel framework, not as versatile for other PHP projects
  • Less mature project with fewer contributors and stars on GitHub

Code Comparison

searchable:

$results = Article::search('Lorem ipsum')->get();

laravel-searchable:

$searchResults = (new Search())
    ->registerModel(User::class, 'name')
    ->registerModel(Post::class, 'title')
    ->search('john');

Key Differences

  • searchable is a more general-purpose PHP package, while laravel-searchable is Laravel-specific
  • laravel-searchable offers multi-model search out of the box, whereas searchable focuses on single model searches
  • searchable provides more advanced features like geospatial search and custom search algorithms

Use Cases

  • Choose searchable for non-Laravel PHP projects or when advanced search features are required
  • Opt for laravel-searchable when working within a Laravel ecosystem and need simple multi-model search functionality

Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch

Pros of laravel-scout-tntsearch-driver

  • Integrates seamlessly with Laravel Scout, providing a unified search interface
  • Offers full-text search capabilities with advanced features like fuzzy matching and boosting
  • Supports multiple languages and stemming out of the box

Cons of laravel-scout-tntsearch-driver

  • Requires additional setup and configuration compared to searchable
  • May have a steeper learning curve for developers new to Laravel Scout
  • Performance might be slower for very large datasets compared to simpler solutions

Code Comparison

searchable:

class Post extends Model
{
    use Searchable;
    
    protected $searchable = [
        'columns' => [
            'posts.title' => 10,
            'posts.content' => 5,
        ],
    ];
}

laravel-scout-tntsearch-driver:

class Post extends Model
{
    use Searchable;
    
    public function toSearchableArray()
    {
        return [
            'title' => $this->title,
            'content' => $this->content,
        ];
    }
}

Both libraries offer simple integration with Laravel models, but laravel-scout-tntsearch-driver provides more flexibility in defining searchable data through the toSearchableArray() method. searchable uses a more declarative approach with the $searchable property, which may be easier for quick setup but less customizable.

Easy creation of slugs for your Eloquent models in Laravel

Pros of eloquent-sluggable

  • Focused specifically on slug generation for Eloquent models
  • Offers more advanced slug customization options (e.g., custom separators, reserved words)
  • Provides built-in handling for slug uniqueness and conflict resolution

Cons of eloquent-sluggable

  • Limited to slug generation, lacks broader search functionality
  • May require additional setup for complex slug scenarios
  • Potentially overkill for simple slug requirements

Code Comparison

eloquent-sluggable:

use Cviebrock\EloquentSluggable\Sluggable;

class Post extends Model
{
    use Sluggable;

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}

searchable:

use Nicolaslopezj\Searchable\SearchableTrait;

class Post extends Model
{
    use SearchableTrait;

    protected $searchable = [
        'columns' => [
            'posts.title' => 10,
            'posts.content' => 5
        ]
    ];
}

While eloquent-sluggable focuses on generating and managing slugs for Eloquent models, searchable provides a broader search functionality across multiple model attributes. eloquent-sluggable offers more advanced slug customization but is limited to that specific use case. searchable, on the other hand, enables flexible search capabilities but may require additional work for slug generation if needed.

Add tags and taggable behaviour to your Laravel app

Pros of laravel-tags

  • More comprehensive tagging functionality, including tag types and custom tag models
  • Better integration with Laravel's ecosystem and conventions
  • Active development and maintenance with frequent updates

Cons of laravel-tags

  • Focused solely on tagging, lacking general search capabilities
  • May be overkill for simple tagging needs
  • Requires more setup and configuration compared to searchable

Code Comparison

searchable:

class Post extends Model
{
    use Searchable;

    protected $searchable = [
        'columns' => [
            'posts.title' => 10,
            'posts.content' => 5,
        ],
    ];
}

laravel-tags:

class Post extends Model
{
    use HasTags;

    public function tags(): MorphToMany
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

Summary

searchable is a lightweight package focused on adding search functionality to Laravel models, while laravel-tags is a more comprehensive solution for tagging models in Laravel applications. searchable is simpler to set up and use for basic search needs, but laravel-tags offers more advanced tagging features and better integration with Laravel's ecosystem. The choice between the two depends on the specific requirements of your project and whether you need general search capabilities or dedicated tagging functionality.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Searchable, a search trait for Laravel

Searchable is a trait for Laravel 4.2+ and Laravel 5.0 that adds a simple search function to Eloquent Models.

Searchable allows you to perform searches in a table giving priorities to each field for the table and it's relations.

This is not optimized for big searches, but sometimes you just need to make it simple (Although it is not slow).

Installation

Simply add the package to your composer.json file and run composer update.

"nicolaslopezj/searchable": "1.*"

Usage

Add the trait to your model and your search rules.

use Nicolaslopezj\Searchable\SearchableTrait;

class User extends \Eloquent
{
    use SearchableTrait;

    /**
     * Searchable rules.
     *
     * @var array
     */
    protected $searchable = [
        /**
         * Columns and their priority in search results.
         * Columns with higher values are more important.
         * Columns with equal values have equal importance.
         *
         * @var array
         */
        'columns' => [
            'users.first_name' => 10,
            'users.last_name' => 10,
            'users.bio' => 2,
            'users.email' => 5,
            'posts.title' => 2,
            'posts.body' => 1,
        ],
        'joins' => [
            'posts' => ['users.id','posts.user_id'],
        ],
    ];

    public function posts()
    {
        return $this->hasMany('Post');
    }

}

Now you can search your model.

// Simple search
$users = User::search($query)->get();

// Search and get relations
// It will not get the relations if you don't do this
$users = User::search($query)
            ->with('posts')
            ->get();

Search Paginated

As easy as laravel default queries

// Search with relations and paginate
$users = User::search($query)
            ->with('posts')
            ->paginate(20);

Mix queries

Search method is compatible with any eloquent method. You can do things like this:

// Search only active users
$users = User::where('status', 'active')
            ->search($query)
            ->paginate(20);

Custom Threshold

The default threshold for accepted relevance is the sum of all attribute relevance divided by 4. To change this value you can pass in a second parameter to search() like so:

// Search with lower relevance threshold
$users = User::where('status', 'active')
            ->search($query, 0)
            ->paginate(20);

The above, will return all users in order of relevance.

Entire Text search

By default, multi-word search terms are split and Searchable searches for each word individually. Relevance plays a role in prioritizing matches that matched on multiple words. If you want to prioritize matches that include the multi-word search (thus, without splitting into words) you can enable full text search by setting the third value to true. Example:

// Prioritize matches containing "John Doe" above matches containing only "John" or "Doe".
$users = User::search("John Doe", null, true)->get();

If you explicitly want to search for full text matches only, you can disable multi-word splitting by setting the fourth parameter to true.

// Do not include matches that only matched "John" OR "Doe".
$users = User::search("John Doe", null, true, true)->get();

How does it work?

Searchable builds a query that search through your model using Laravel's Eloquent. Here is an example query

Eloquent Model:

use Nicolaslopezj\Searchable\SearchableTrait;

class User extends \Eloquent
{
    use SearchableTrait;

    /**
     * Searchable rules.
     *
     * @var array
     */
    protected $searchable = [
        'columns' => [
            'first_name' => 10,
            'last_name' => 10,
            'bio' => 2,
            'email' => 5,
        ],
    ];

}

Search:

$search = User::search('Sed neque labore', null, true)->get();

Result:

select `users`.*, 

-- If third parameter is set as true, it will check if the column starts with the search
-- if then it adds relevance * 30
-- this ensures that relevant results will be at top
(case when first_name LIKE 'Sed neque labore%' then 300 else 0 end) + 

-- For each column you specify makes 3 "ifs" containing 
-- each word of the search input and adds relevace to 
-- the row

-- The first checks if the column is equal to the word,
-- if then it adds relevance * 15
(case when first_name LIKE 'Sed' || first_name LIKE 'neque' || first_name LIKE 'labore' then 150 else 0 end) + 

-- The second checks if the column starts with the word,
-- if then it adds relevance * 5
(case when first_name LIKE 'Sed%' || first_name LIKE 'neque%' || first_name LIKE 'labore%' then 50 else 0 end) + 

-- The third checks if the column contains the word, 
-- if then it adds relevance * 1
(case when first_name LIKE '%Sed%' || first_name LIKE '%neque%' || first_name LIKE '%labore%' then 10 else 0 end) + 

-- Repeats with each column
(case when last_name LIKE 'Sed' || last_name LIKE 'neque' || last_name LIKE 'labore' then 150 else 0 end) + 
(case when last_name LIKE 'Sed%' || last_name LIKE 'neque%' || last_name LIKE 'labore%' then 50 else 0 end) +
(case when last_name LIKE '%Sed%' || last_name LIKE '%neque%' || last_name LIKE '%labore%' then 10 else 0 end) + 

(case when bio LIKE 'Sed' || bio LIKE 'neque' || bio LIKE 'labore' then 30 else 0 end) + 
(case when bio LIKE 'Sed%' || bio LIKE 'neque%' || bio LIKE 'labore%' then 10 else 0 end) + 
(case when bio LIKE '%Sed%' || bio LIKE '%neque%' || bio LIKE '%labore%' then 2 else 0 end) + 

(case when email LIKE 'Sed' || email LIKE 'neque' || email LIKE 'labore' then 75 else 0 end) + 
(case when email LIKE 'Sed%' || email LIKE 'neque%' || email LIKE 'labore%' then 25 else 0 end) + 
(case when email LIKE '%Sed%' || email LIKE '%neque%' || email LIKE '%labore%' then 5 else 0 end) 

as relevance 
from `users` 
group by `id` 

-- Selects only the rows that have more than
-- the sum of all attributes relevances and divided by 4
-- Ej: (20 + 5 + 2) / 4 = 6.75
having relevance > 6.75 

-- Orders the results by relevance
order by `relevance` desc

Contributing

Anyone is welcome to contribute. Fork, make your changes, and then submit a pull request.

Support via Gittip