Text analysis is configured by implementing the IndexSettings interface on your model. This allows you to define custom analyzers and filters (such as synonyms) that Elasticsearch will use during indexing and searching.
To implement synonyms, you can use the SynonymFilter and StandardAnalyzer classes. For example, to make searching for 'Vue' also return results for 'React', you would define a synonym mapping and include a lowercase filter to ensure case-insensitive matching.
Note: Custom analyzers and synonym filters are computationally 'expensive' for Elasticsearch. Before implementing them, consider if wildcards or fuzzy queries can achieve your goal.
<?php
namespace App\
Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Model;
use JeroenG\Explorer\Application\Explored;
use JeroenG\Explorer\Application\IndexSettings;
use JeroenG\Explorer\Domain\Analysis\Analysis;
use JeroenG\Explorer\Domain\Analysis\Analyzer\StandardAnalyzer;
use JeroenG\Explorer\Domain\Analysis\Filter\SynonymFilter;
use Laravel\Scout\Searchable;
class Post extends Model implements Explored, IndexSettings
{
use HasFactory;
use Searchable;
protected $fillable = ['title', 'published'];
public function mappableAs(): array
{
return [
'id' => 'keyword',
'title' => [
'type' => 'text',
'analyzer' => 'frameworks',
],
'published' => 'boolean',
'created_at' => 'date',
];
}
public function indexSettings(): array
{
$synonymFilter = new SynonymFilter();
$synonymFilter->setSynonyms(['vue => react']);
$synonymAnalyzer = new StandardAnalyzer('frameworks');
$synonymAnalyzer->setFilters(['lowercase', $synonymFilter]);
return (new Analysis())
->addAnalyzer($synonymAnalyzer)
->addFilter($synonymFilter)
->build();
}
}