From f101c1a622fbce7e22ad94bc93b17f234cc841cb Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Sat, 24 Mar 2018 18:46:31 +0000 Subject: [PATCH] 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. --- app/Book.php | 1 + app/Chapter.php | 2 ++ app/Entity.php | 9 +++++++++ app/Http/Controllers/SearchController.php | 3 +-- app/Services/SearchService.php | 17 +++++++++-------- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/Book.php b/app/Book.php index 457a4c928..51ea226b4 100644 --- a/app/Book.php +++ b/app/Book.php @@ -2,6 +2,7 @@ class Book extends Entity { + public $searchFactor = 2; protected $fillable = ['name', 'description', 'image_id']; diff --git a/app/Chapter.php b/app/Chapter.php index 6dab9dc47..3726c57f4 100644 --- a/app/Chapter.php +++ b/app/Chapter.php @@ -2,6 +2,8 @@ class Chapter extends Entity { + public $searchFactor = 1.3; + protected $fillable = ['name', 'description', 'priority', 'book_id']; protected $with = ['book']; diff --git a/app/Entity.php b/app/Entity.php index 1ea4e8dac..aeeab4960 100644 --- a/app/Entity.php +++ b/app/Entity.php @@ -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 '/'; } + } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 0827eeb71..ddc92f705 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -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 ]); } diff --git a/app/Services/SearchService.php b/app/Services/SearchService.php index 6786c5cf4..cb445eed1 100644 --- a/app/Services/SearchService.php +++ b/app/Services/SearchService.php @@ -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();