01
DecThere are many techniques to add search functionality to your Laravel project. You can use the Laravel Query Builder, use the Laravel Scout package to integrate with Algolia, or use different third-party packages. Today I’m introducing a new package called travel Cross Eloquent Search. This Laravel package allows you to search through multiple Eloquent models. It supports sorting, pagination, scoped queries, eager load relationships, and searching through single or multiple columns.
This package has a lot of awesome features that make it worthy to utilize in your projects.
You can install this package via composer by running this command:
composer require protonemedia/laravel-cross-eloquent-search
Start your search query by adding one or more models to search through. Call the add
method with the model’s class name and the column you want to search through. Then call the get
method with the search term, and you’ll get a \Illuminate\Database\Eloquent\Collection
instance with the results.
The results are sorted in ascending order by the updated column by default. In most cases, this column is updated_at
. If you’ve customized your model’s UPDATED_AT
constant, or overwritten the getUpdatedAtColumn
method, this package will use the customized column. Of course, you can order by another column as well.
use ProtoneMedia\LaravelCrossEloquentSearch\Search;
$results = Search::add(Post::class, 'title')
->add(Video::class, 'title')
->get('howto');
If you care about indentation, you can optionally use the new method on the facade
:
Search::new()
->add(Post::class, 'title')
->add(Video::class, 'title')
->get('howto');
You can add multiple models at once by using the addMany
method:
Search::addMany([
[Post::class, 'title'],
[Video::class, 'title'],
])->get('howto');
There’s also an addWhen
method, that adds the model when the first argument given to the method evaluates to true
:
Search::new()
->addWhen($user, Post::class, 'title')
->addWhen($user->isAdmin(), Video::class, 'title')
->get('howto');
Multi-word search is supported out of the box. Simply wrap your phrase into double quotes.
Search::add(Post::class, 'title')
->add(Video::class, 'title')
->get('"macos big sur"');
You can disable the parsing of the search term by calling the dontParseTerm
method, which gives you the same results as using double-quotes.
Search::add(Post::class, 'title')
->add(Video::class, 'title')
->dontParseTerm()
->get('macos big sur');
If you want to sort the results by another column, you can pass that column to the add method as a third parameter. Call the orderByDesc
method to sort the results in descending order.
Search::add(Post::class, 'title', 'published_at')
->add(Video::class, 'title', 'released_at')
->orderByDesc()
->get('learn');
You can call the orderByRelevance
method to sort the results by the number of occurrences of the search terms. Imagine these two sentences:
If you search for Apple iPad, the second sentence will come up first, as there are more matches of the search terms.
Search::add(Post::class, 'title')
->beginWithWildcard()
->orderByRelevance()
->get('Apple iPad');
Ordering by relevance is not supported if you’re searching through (nested
) relationships.
To sort the results by model type, you can use the orderByModel
method by giving it your preferred order of the models:
Search::new()
->add(Comment::class, ['body'])
->add(Post::class, ['title'])
->add(Video::class, ['title', 'description'])
->orderByModel([
Post::class, Video::class, Comment::class,
])
->get('Artisan School');
We highly recommend paginating your results. Call the paginate method before the get method, and you’ll get an instance of \Illuminate\Contracts\Pagination\LengthAwarePaginator
as a result. The paginate method takes three (optional) parameters to customize the paginator. These arguments are the same as Laravel’s database paginator.
Search::add(Post::class, 'title')
->add(Video::class, 'title')
->paginate()
// or
->paginate($perPage = 15, $pageName = 'page', $page = 1)
->get('build');
You may also use simple pagination. This will return an instance of \Illuminate\Contracts\Pagination\Paginator
, which is not length aware:
Search::add(Post::class, ‘title’)
->add(Video::class, ‘title’)
->simplePaginate()
// or
->simplePaginate($perPage = 15, $pageName = 'page', $page = 1)
->get('build');
You can search through multiple columns by passing an array of columns as the second argument.
Search::add(Post::class, ['title', 'body'])
->add(Video::class, ['title', 'subtitle'])
->get('eloquent');
In this blog, I’ve explained only some of the features & options of this package but there are a lot more options present in this package. If you are interested then you can visit their detailed documentation with code examples on Github.
Published at : 01-12-2021
I am a highly results-driven professional with 12+ years of collective experience in the grounds of web application development especially in laravel, native android application development in java, and desktop application development in the dot net framework. Now managing a team of expert developers at Codebrisk.
Launch project