Skip to content

Commit

Permalink
[TASK] Improve suggestion endpoint to expose slugs and support vendor (
Browse files Browse the repository at this point in the history
  • Loading branch information
damienalexandre authored Dec 3, 2024
1 parent d0e22c7 commit 06cbf57
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 40 deletions.
5 changes: 5 additions & 0 deletions .ddev/nginx/cors.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Make it easy to test from another DDEV project like render-guides
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Headers *;
add_header Access-Control-Allow-Credentials *;
53 changes: 21 additions & 32 deletions src/Controller/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ public function index(): Response
#[Route(path: '/search', name: 'searchresult')]
public function search(Request $request): Response
{
if ($request->query->get('q', '') === '') {
$searchDemand = SearchDemand::createFromRequest($request);
if ($searchDemand->getQuery() === '' && empty($searchDemand->getFilters())) {
return $this->redirectToRoute('index');
}

$searchDemand = SearchDemand::createFromRequest($request);

return $this->render('search/search.html.twig', [
'q' => $searchDemand->getQuery(),
'searchScope' => $searchDemand->getScope(),
Expand All @@ -59,35 +58,25 @@ public function suggest(Request $request): Response
$searchResults = $this->elasticRepository->searchDocumentsForSuggest($searchDemand);
$jsonData['time'] = $searchResults['time'];

$jsonData['results'] = array_map(static function ($result) {
return $result->getData();
}, $searchResults['results']);

return new JsonResponse($jsonData);
}

#[Route(path: '/suggest/list', name: 'suggest-list')]
public function suggestList(Request $request): Response
{
$searchDemand = SearchDemand::createFromRequest($request);
$jsonData = [
'demand' => $searchDemand->toArray(),
'suggest' => $this->elasticRepository->suggestScopes($searchDemand)
];

return new JsonResponse($jsonData);
}

#[Route(path: '/suggest/results', name: 'suggest-results')]
public function suggestResults(Request $request): Response
{
$searchDemand = SearchDemand::createFromRequest($request);

$searchResults = $this->elasticRepository->searchDocumentsForSuggest($searchDemand);
$jsonData['time'] = $searchResults['time'];

$jsonData['results'] = array_map(static function ($result) {
return $result->getData();
$jsonData['results'] = array_map(static function ($result) use ($searchDemand) {
$data = $result->getData();

// If a major version is seeked, replace the version in the slug to match.
if ($searchDemand->getFilters()['major_versions'] ?? null) {
$targetVersion = null;
foreach ($data['manual_version'] as $version) {
if (str_starts_with($version, $searchDemand->getFilters()['major_versions'][0].'.')) {
$targetVersion = $version;
break;
}
}

if ($targetVersion) {
$data['manual_slug'] = str_replace($data['manual_version'][0], $targetVersion, $data['manual_slug']);
}
}

return $data;
}, $searchResults['results']);

return new JsonResponse($jsonData);
Expand Down
4 changes: 4 additions & 0 deletions src/Dto/SearchDemand.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public static function createFromRequest(Request $request): SearchDemand
if ($scope) {
$filters['manual_slug'] = [$scope];
}
$vendor = trim(htmlspecialchars(strip_tags((string)$request->query->get('vendor'))), '/');
if ($vendor) {
$filters['manual_vendor'] = [$vendor];
}

return new self($query, $scope, max($page, 1), $filters, $areSuggestionsHighlighted);
}
Expand Down
47 changes: 39 additions & 8 deletions src/Repository/ElasticRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,13 @@ public function suggestScopes(SearchDemand $searchDemand): array
'manual_vendor' => [
'removeIfField' => 'manual_package'
],
'manual_package' => [],
'manual_package' => [
'addTopHits' => true,
],
'option' => [],
'manual_version' => []
'manual_version' => [
'field' => 'major_versions'
]
];

$multiSearch = new MultiSearch($this->elasticClient);
Expand All @@ -234,6 +238,7 @@ public function suggestScopes(SearchDemand $searchDemand): array
'query' => $search,
'fields' =>
[
$settings['field'] ?? $scope,
$scope,
$scope . '.small_suggest',
$scope . '.large_suggest',
Expand All @@ -252,16 +257,24 @@ public function suggestScopes(SearchDemand $searchDemand): array
'aggs' => [
$scope => [
'terms' => [
'field' => $scope,
'field' => $settings['field'] ?? $scope,
'size' => 5
],
],
],
'fields' => [$scope],
'_source' => false,
'size' => 0
];

if ($settings['addTopHits'] ?? false) {
$singleQuery['aggs'][$scope]['aggs']['manual_slug_hits'] = [
'top_hits' => [
'size' => 1,
'_source' => ['manual_version', 'manual_slug']
]
];
}

$searchObj = new Search($this->elasticClient);

$filters = $searchDemand->getFilters();
Expand Down Expand Up @@ -295,7 +308,6 @@ public function suggestScopes(SearchDemand $searchDemand): array
}

$results = $multiSearch->search();

$totalTime = 0;
$expectedAggregations = array_keys($suggestions);

Expand All @@ -307,7 +319,26 @@ public function suggestScopes(SearchDemand $searchDemand): array
continue;
}

$suggestionsForCurrentQuery = array_column($aggregation['buckets'], 'key');
$suggestionsForCurrentQuery = [];

foreach ($aggregation['buckets'] as $bucket) {
// Add URL on manual_package
if (isset($bucket['manual_slug_hits']['hits']['hits'][0])) {
if ($searchDemand->getFilters()['major_versions'] ?? null) {
$slug = $bucket['manual_slug_hits']['hits']['hits'][0]['_source']['manual_slug'];
} else {
$version = end($bucket['manual_slug_hits']['hits']['hits'][0]['_source']['manual_version']);
$slug = str_replace($version, 'main', $bucket['manual_slug_hits']['hits']['hits'][0]['_source']['manual_slug']);
}

$suggestionsForCurrentQuery[] = [
'slug' => $slug,
'title' => $bucket['key'],
];
} else {
$suggestionsForCurrentQuery[] = ['title' => $bucket['key']];
}
}

if ($suggestionsForCurrentQuery === []) {
unset($suggestions[$aggsName]);
Expand Down Expand Up @@ -476,7 +507,7 @@ private function getDefaultSearchQuery(SearchDemand $searchDemand): array
'query' => [
'bool' => [
'must' => [
[
$searchTerms ? [
'query_string' => [
'query' => $searchTerms,
'fields' => [
Expand All @@ -486,7 +517,7 @@ private function getDefaultSearchQuery(SearchDemand $searchDemand): array
'manual_title'
]
],
],
] : ['match_all' => new \stdClass()],
],
],
],
Expand Down

0 comments on commit 06cbf57

Please sign in to comment.