<?php
use Illuminate\Database\Eloquent\Model;
use TeamTNT\TNTSearch\Facades\TNTSearch;
trait Searchable
{
/**
* Auto update search index using model events.
*
* @return void
*/
protected static function syncSearchableIndex()
{
if (config('services.tntsearch.sync') && ! app()->runningInConsole()) {
static::created([__CLASS__, 'insertToIndex']);
static::updated([__CLASS__, 'updateIndex']);
static::deleted([__CLASS__, 'deleteFromIndex']);
}
}
/**
* Dele a entity from the search index.
*
* @param \Illuminate\Database\Eloquent\Model $entity
*
* @return void
*/
public static function deleteFromIndex(Model $entity)
{
$entity->createIndexIfNotExists();
TNTSearch::selectIndex($entity->searchableAs());
$index = TNTSearch::getIndex();
$index->delete($entity->getPrimaryKeyColumn());
}
/**
* Update a entity in the search index.
*
* @param \Illuminate\Database\Eloquent\Model $entity
*
* @return void
*/
public static function updateIndex(Model $entity)
{
$entity->createIndexIfNotExists();
TNTSearch::selectIndex($entity->searchableAs());
$index = TNTSearch::getIndex();
$index->update($entity->getPrimaryKeyColumn(), $entity->toSearchableArray());
}
/**
* Insert a new entity in the search index.
*
* @param \Illuminate\Database\Eloquent\Model $entity
*
* @return void
*/
public static function insertToIndex(Model $entity)
{
$entity->createIndexIfNotExists();
TNTSearch::selectIndex($entity->searchableAs());
$index = TNTSearch::getIndex();
$index->insert($entity->toSearchableArray());
}
/**
* Create a new search index if doesn't exists one.
*
* @return void
*/
public function createIndexIfNotExists()
{
$indexFile = sprintf('%s/%s', config('services.tntsearch.storage'), $this->searchableAs());
if (! is_file($indexFile)) {
TNTSearch::createIndex($this->searchableAs());
}
}
/**
* Perform a search against the model's indexed data.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param string $search
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSearch($builder, $query)
{
TNTSearch::selectIndex($this->searchableAs());
$results = TNTSearch::search($query, $this->count());
$ids = $results['ids'];
$column = $this->getPrimaryKeyColumn();
$orderByQuery = sprintf('FIELD (%s, %s)', $column, implode(', ', $ids));
return $builder->whereIn($column, $ids)->orderByRaw($orderByQuery);
}
/**
* Get the primary key column name.
*
* @return string
*/
private function getPrimaryKeyColumn()
{
return sprintf('%s.%s', $this->getTable(), $this->getKeyName());
}
/**
* Get the index name for the model.
*
* @return string
*/
public function searchableAs()
{
return sprintf('%s.index', strtolower(class_basename(get_called_class())));
}
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
return $this->toArray();
}
}
Last active
August 15, 2018 13:17
-
-
Save flyingluscas/fabd528c19eca18a9c173082395e1cff to your computer and use it in GitHub Desktop.
TNT Searchable Trait
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment