Laravel 5.1 package for full-text search over Eloquent models based on ZendSearch Lucene.
Require this package in your composer.json and run composer update:
{
"require": {
"nqxcode/laravel-lucene-search": "2.1.*"
}
}
After updating composer, add the ServiceProvider to the providers array in app/config/app.php
'providers' => [
Nqxcode\LuceneSearch\ServiceProvider::class,
],
If you want to use the facade to search, add this to your facades in app/config/app.php
:
'aliases' => [
'Search' => Nqxcode\LuceneSearch\Facade::class,
],
Publish the config file into your project by running:
php artisan vendor:publish --provider="Nqxcode\LuceneSearch\ServiceProvider"
In published config file add descriptions for models which need to be indexed, for example:
'index' => [
// ...
namespace\FirstModel::class => [
'fields' => [
'name', 'full_description', // Fields for indexing.
]
],
namespace\SecondModel::class => [
'fields' => [
'name', 'short_description', // Fields for indexing.
]
],
// ...
],
You can also index values of optional fields (dynamic fields). For enable indexing for optional fields:
- In config for each necessary model add following option:
'optional_attributes' => true
// or
'optional_attributes' => [
'field' => 'custom_name' // with specifying of accessor name
]
- In model add special accessor, that returns list of
field-name => field-value
. By defaultgetOptionalAttributesAttribute
accessor will be used. In case accessor name specified in configgetCustomNameAttribute
accessor will be used.
Example:
In config file:
namespace\FirstModel::class => [
'fields' => [
'name', 'full_description', // Fixed fields for indexing.
],
'optional_attributes' => true // Enable indexing for dynamic fields
],
In model add following accessor:
public function getOptionalAttributesAttribute()
{
return [
'optional_attribute1' => "value1",
'optional_attribute2' => "value2",
];
}
By default the following filters are used by search:
- Stemming filter for english/russian words,
- Stopword filters for english/russian words.
This filters can be deleted or replaced with others.
'analyzer' => [
'filters' => [
// Default stemming filter.
Nqxcode\Stemming\TokenFilterEnRu::class,
],
// List of paths to files with stopwords.
'stopwords' => Nqxcode\LuceneSearch\Analyzer\Stopwords\Files::get(),
],
For building of search index run:
php artisan search:rebuild
For clearing of search index run:
php artisan search:clear
For filtering of models in search results each model's class can implements Searchable
.
For example:
use Illuminate\Database\Eloquent\Model;
use Nqxcode\LuceneSearch\Model\Searchable;
class Dummy extends Model implements Searchable
{
// ...
/**
* Is the model available for searching?
*/
public function isSearchable()
{
return $this->publish;
}
// ...
}
For register of necessary events (save/update/delete) use Nqxcode\LuceneSearch\Model\SearchTrait
in target model:
use Illuminate\Database\Eloquent\Model;
use Nqxcode\LuceneSearch\Model\Searchable;
use Nqxcode\LuceneSearch\Model\SearchTrait;
class Dummy extends Model implements Searchable
{
use SearchTrait;
// ...
}
Build query in several ways:
By default, queries which will execute search in the phrase entirely are created.
$query = Search::query('clock'); // search by all fields.
// or
$query = Search::where('name', 'clock'); // search by 'name' field.
// or
$query = Search::query('clock') // search by all fields with
->where('short_description', 'analog'); // filter by 'short_description' field.
For query
and where
methods it is possible to set the following options:
- phrase - phrase match (boolean, true by default)
- proximity - value of distance between words (unsigned integer)
- fuzzy - value of fuzzy (float, 0 ... 1)
- required - should match (boolean, true by default)
- prohibited - should not match (boolean, false by default)
Find all models in which any field contains phrase like 'composite one two phrase':
$query = Search::query('composite phrase', '*', ['proximity' => 2]);
Search by each word in query:
$query = Search::query('composite phrase', '*', ['phrase' => false]);
$query = Search::rawQuery('short_description:"analog"');
// or
$rawQuery = QueryParser::parse('short_description:"analog"');
$query = Search::rawQuery($rawQuery);
For built query are available following actions:
$models = $query->get();
$count = $query->count();
$models = $query->limit(5, 10)->get(); // Limit = 5 and offset = 10
$paginator = $query->paginate(50);
Highlighting of matches is available for any html fragment encoded in utf-8 and is executed only for the last executed request.
Search::find('nearly all words must be highlighted')->get();
$highlighted = Search::highlight('all words');
echo $highlighted;
// Echo: <span class="highlight">all</span> <span class="highlight">words</span>
Package licenced under the MIT license.