From 1d0dcaa240c568b826492b59de313ecbd8df3fb7 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Tue, 9 Jun 2015 19:35:34 +0200 Subject: [PATCH 1/5] PHRAS-442 #time 5h facets returned in API "suggestions" returned in API (as flat facets) --- lib/Alchemy/Phrasea/Controller/Api/V1Controller.php | 1 + .../Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php | 9 +++++++++ .../SearchEngine/Elastic/Search/FacetsResponse.php | 5 +++++ .../Phrasea/SearchEngine/SearchEngineSuggestion.php | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index 3dec948592..a2e0d1f5a2 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -1111,6 +1111,7 @@ class V1Controller extends Controller function (SearchEngineSuggestion $suggestion) { return $suggestion->toArray(); }, $search_result->getSuggestions()->toArray()), + 'facets' => $search_result->getFacets(), 'results' => [], 'query' => $search_result->getQuery(), ]; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php index dcb2b60cc8..8cd30c1499 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php @@ -21,6 +21,7 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure; use Alchemy\Phrasea\SearchEngine\SearchEngineInterface; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; use Alchemy\Phrasea\SearchEngine\SearchEngineResult; +use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion; use Alchemy\Phrasea\Exception\RuntimeException; use Closure; use Doctrine\Common\Collections\ArrayCollection; @@ -290,8 +291,16 @@ class ElasticSearchEngine implements SearchEngineInterface $results[] = ElasticsearchRecordHydrator::hydrate($hit, $n++); } + /** @var FacetsResponse $facets */ $facets = $this->facetsResponseFactory->__invoke($res); + // for es, suggestions are a flat view of facets (api backward compatibility) + $suggestions->clear(); + foreach($facets->getFacets() as $facet) { + foreach($facet['values'] as $value) { + $suggestions->add(new SearchEngineSuggestion($value['query'], $value['value'], $value['count'])); + } + } $query['ast'] = $this->app['query_compiler']->parse($string)->dump(); $query['query_main'] = $recordQuery; $query['query'] = $params['body']; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php index 299e3f2bbe..22a688372b 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php @@ -31,6 +31,11 @@ class FacetsResponse implements JsonSerializable } } + public function getFacets() + { + return $this->facets; + } + private function buildBucketsValues($name, $buckets) { $values = array(); diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineSuggestion.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineSuggestion.php index 3997ea46e2..7d3f18d161 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineSuggestion.php +++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineSuggestion.php @@ -74,7 +74,8 @@ class SearchEngineSuggestion public function toArray() { return [ - 'query' => $this->getSuggestion(), + 'suggestion' => $this->getSuggestion(), + 'query' => $this->getQuery(), 'hits' => $this->getHits(), ]; } From 50ddbbed6098267e54bcf2c8205fbac1032079b4 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 10 Jun 2015 11:19:45 +0200 Subject: [PATCH 2/5] PHRAS-442 #time 10 m cs --- .../Phrasea/Controller/Api/V1Controller.php | 18 +++++++++--------- .../Elastic/Search/FacetsResponse.php | 5 +++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index a2e0d1f5a2..efd3ae30b6 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -1099,19 +1099,19 @@ class V1Controller extends Controller $this->getSearchEngine()->clearCache(); $ret = [ - 'offset_start' => $offsetStart, - 'per_page' => $perPage, + 'offset_start' => $offsetStart, + 'per_page' => $perPage, 'available_results' => $search_result->getAvailable(), - 'total_results' => $search_result->getTotal(), - 'error' => (string)$search_result->getError(), - 'warning' => (string)$search_result->getWarning(), - 'query_time' => $search_result->getDuration(), - 'search_indexes' => $search_result->getIndexes(), - 'suggestions' => array_map( + 'total_results' => $search_result->getTotal(), + 'error' => (string)$search_result->getError(), + 'warning' => (string)$search_result->getWarning(), + 'query_time' => $search_result->getDuration(), + 'search_indexes' => $search_result->getIndexes(), + 'suggestions' => array_map( function (SearchEngineSuggestion $suggestion) { return $suggestion->toArray(); }, $search_result->getSuggestions()->toArray()), - 'facets' => $search_result->getFacets(), + 'facets' => $search_result->getFacets(), 'results' => [], 'query' => $search_result->getQuery(), ]; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php index 22a688372b..7a81cf3a7d 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php @@ -31,6 +31,11 @@ class FacetsResponse implements JsonSerializable } } + /** + * Term aggregates + * + * @return array + */ public function getFacets() { return $this->facets; From 842ce637e74425f37ef0eb5d84decef44a8022b5 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 10 Jun 2015 11:28:05 +0200 Subject: [PATCH 3/5] PHRAS-442 #time 10 m cs --- .../Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php index 347d797676..1343878ad9 100644 --- a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php +++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php @@ -44,7 +44,7 @@ class SearchEngineSuggestionTest extends \PhraseanetTestCase $hits = 35; $suggestion = new SearchEngineSuggestion($query, $words, $hits); - $this->assertEquals(['query' => $words, 'hits' => 35], $suggestion->toArray()); + $this->assertEquals(['query' => $query, 'hits' => 35, 'suggestion' => $words], $suggestion->toArray()); } public function testToArrayWithNullValue() @@ -54,6 +54,6 @@ class SearchEngineSuggestionTest extends \PhraseanetTestCase $hits = null; $suggestion = new SearchEngineSuggestion($query, $words, $hits); - $this->assertEquals(['query' => $words, 'hits' => null], $suggestion->toArray()); + $this->assertEquals(['query' => $words, 'hits' => null, 'suggestion' => $words], $suggestion->toArray()); } } From 0584fddfc88990747cf52e4bc1dd15220062c249 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 10 Jun 2015 13:05:43 +0200 Subject: [PATCH 4/5] PHRAS-442 #time 2 m fix tests --- .../Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php index 1343878ad9..b6a8a6e614 100644 --- a/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php +++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/SearchEngineSuggestionTest.php @@ -54,6 +54,6 @@ class SearchEngineSuggestionTest extends \PhraseanetTestCase $hits = null; $suggestion = new SearchEngineSuggestion($query, $words, $hits); - $this->assertEquals(['query' => $words, 'hits' => null, 'suggestion' => $words], $suggestion->toArray()); + $this->assertEquals(['query' => $query, 'hits' => null, 'suggestion' => $words], $suggestion->toArray()); } } From 2ee19c17f50b36d1dc37ac091d43cca7c02073e1 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Mon, 22 Jun 2015 19:07:56 +0200 Subject: [PATCH 5/5] PHRAS-442 #time 1h less coupling (mdarse) --- .../Elastic/ElasticSearchEngine.php | 26 ++++++++++--------- .../Elastic/Search/FacetsResponse.php | 19 ++++++++++---- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php index 8cd30c1499..13b310e8af 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php @@ -21,7 +21,6 @@ use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Structure; use Alchemy\Phrasea\SearchEngine\SearchEngineInterface; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; use Alchemy\Phrasea\SearchEngine\SearchEngineResult; -use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion; use Alchemy\Phrasea\Exception\RuntimeException; use Closure; use Doctrine\Common\Collections\ArrayCollection; @@ -284,7 +283,6 @@ class ElasticSearchEngine implements SearchEngineInterface $res = $this->client->search($params); $results = new ArrayCollection(); - $suggestions = new ArrayCollection(); $n = 0; foreach ($res['hits']['hits'] as $hit) { @@ -294,21 +292,25 @@ class ElasticSearchEngine implements SearchEngineInterface /** @var FacetsResponse $facets */ $facets = $this->facetsResponseFactory->__invoke($res); - // for es, suggestions are a flat view of facets (api backward compatibility) - $suggestions->clear(); - foreach($facets->getFacets() as $facet) { - foreach($facet['values'] as $value) { - $suggestions->add(new SearchEngineSuggestion($value['query'], $value['value'], $value['count'])); - } - } $query['ast'] = $this->app['query_compiler']->parse($string)->dump(); $query['query_main'] = $recordQuery; $query['query'] = $params['body']; $query['query_string'] = json_encode($params['body']); - return new SearchEngineResult($results, json_encode($query), $res['took'], $offset, - $res['hits']['total'], $res['hits']['total'], null, null, $suggestions, [], - $this->indexName, $facets); + return new SearchEngineResult( + $results, // ArrayCollection of results + json_encode($query), + $res['took'], // duration + $offset, // offset start + $res['hits']['total'], // available + $res['hits']['total'], // total + null, // error + null, // warning + $facets->getAsSuggestions(), // ArrayCollection of suggestions + [], // propositions + $this->indexName, + $facets + ); } /** diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php index 7a81cf3a7d..2b1c3450bf 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Search/FacetsResponse.php @@ -3,6 +3,8 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search; use Alchemy\Phrasea\Exception\RuntimeException; +use Alchemy\Phrasea\SearchEngine\SearchEngineSuggestion; +use Doctrine\Common\Collections\ArrayCollection; use JsonSerializable; class FacetsResponse implements JsonSerializable @@ -32,13 +34,20 @@ class FacetsResponse implements JsonSerializable } /** - * Term aggregates - * - * @return array + * @return ArrayCollection */ - public function getFacets() + public function getAsSuggestions() { - return $this->facets; + $suggestions = new ArrayCollection(); + + // for es, suggestions are a flat view of facets (api backward compatibility) + foreach ($this->facets as $facet) { + foreach ($facet['values'] as $value) { + $suggestions->add(new SearchEngineSuggestion($value['query'], $value['value'], $value['count'])); + } + } + + return $suggestions; } private function buildBucketsValues($name, $buckets)