Made search more efficient and tweaked weighting

Added per-entity weighting changes.
Now Books score higher than chapters which score higher than pages.

Reduced queries required on search by only searching once but at a
higher count to see if there's another page.
This commit is contained in:
Dan Brown 2018-03-24 18:46:31 +00:00
parent 3df7d828eb
commit f101c1a622
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
5 changed files with 22 additions and 10 deletions

View File

@ -2,6 +2,7 @@
class Book extends Entity
{
public $searchFactor = 2;
protected $fillable = ['name', 'description', 'image_id'];

View File

@ -2,6 +2,8 @@
class Chapter extends Entity
{
public $searchFactor = 1.3;
protected $fillable = ['name', 'description', 'priority', 'book_id'];
protected $with = ['book'];

View File

@ -5,8 +5,16 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
class Entity extends Ownable
{
/**
* @var string - Name of property where the main text content is found
*/
public $textField = 'description';
/**
* @var float - Multiplier for search indexing.
*/
public $searchFactor = 1.0;
/**
* Compares this entity to another given entity.
* Matches by comparing class and id.
@ -193,4 +201,5 @@ class Entity extends Ownable
{
return '/';
}
}

View File

@ -40,13 +40,12 @@ class SearchController extends Controller
$nextPageLink = baseUrl('/search?term=' . urlencode($searchTerm) . '&page=' . ($page+1));
$results = $this->searchService->searchEntities($searchTerm, 'all', $page, 20);
$hasNextPage = $this->searchService->searchEntities($searchTerm, 'all', $page+1, 20)['count'] > 0;
return view('search/all', [
'entities' => $results['results'],
'totalResults' => $results['total'],
'searchTerm' => $searchTerm,
'hasNextPage' => $hasNextPage,
'hasNextPage' => $results['has_more'],
'nextPageLink' => $nextPageLink
]);
}

View File

@ -72,7 +72,6 @@ class SearchService
$terms = $this->parseSearchString($searchString);
$entityTypes = array_keys($this->entities);
$entityTypesToSearch = $entityTypes;
$results = collect();
if ($entityType !== 'all') {
$entityTypesToSearch = $entityType;
@ -80,21 +79,23 @@ class SearchService
$entityTypesToSearch = explode('|', $terms['filters']['type']);
}
$results = collect();
$total = 0;
foreach ($entityTypesToSearch as $entityType) {
if (!in_array($entityType, $entityTypes)) {
continue;
}
$search = $this->searchEntityTable($terms, $entityType, $page, $count);
$total += $this->searchEntityTable($terms, $entityType, $page, $count, true);
$search = $this->searchEntityTable($terms, $entityType, $page, $count + 1);
$total += $this->searchEntityTable($terms, $entityType, $page, $count + 1, true);
$results = $results->merge($search);
}
return [
'total' => $total,
'count' => count($results),
'results' => $results->sortByDesc('score')->values()
'has_more' => $results->count() > $count,
'results' => $results->sortByDesc('score')->slice(0, $count)->values()
];
}
@ -322,8 +323,8 @@ class SearchService
public function indexEntity(Entity $entity)
{
$this->deleteEntityTerms($entity);
$nameTerms = $this->generateTermArrayFromText($entity->name, 5);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1);
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1 * $entity->searchFactor);
$terms = array_merge($nameTerms, $bodyTerms);
foreach ($terms as $index => $term) {
$terms[$index]['entity_type'] = $entity->getMorphClass();
@ -340,8 +341,8 @@ class SearchService
{
$terms = [];
foreach ($entities as $entity) {
$nameTerms = $this->generateTermArrayFromText($entity->name, 5);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1);
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1 * $entity->searchFactor);
foreach (array_merge($nameTerms, $bodyTerms) as $term) {
$term['entity_id'] = $entity->id;
$term['entity_type'] = $entity->getMorphClass();