From c0d0cdfab9fe020e9637b9fdea4b62faccef7706 Mon Sep 17 00:00:00 2001 From: Aske Ertmann Date: Thu, 13 Sep 2018 13:15:27 +0200 Subject: [PATCH 1/4] TASK: Fix order of arguments in suggest controller --- Classes/Controller/SuggestController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/Controller/SuggestController.php b/Classes/Controller/SuggestController.php index 952cf00..be04a86 100644 --- a/Classes/Controller/SuggestController.php +++ b/Classes/Controller/SuggestController.php @@ -56,13 +56,13 @@ public function initializeObject() } /** + * @param string $term * @param string $contextNodeIdentifier * @param string $dimensionCombination - * @param string $term * @return void * @throws QueryBuildingException */ - public function indexAction($contextNodeIdentifier, $dimensionCombination, $term) + public function indexAction($term, $contextNodeIdentifier, $dimensionCombination) { if ($this->elasticSearchClient === null) { throw new \RuntimeException('The SuggestController needs an ElasticSearchClient, it seems you run without the flowpack/elasticsearch-contentrepositoryadaptor package, though.', 1487189823); @@ -79,7 +79,7 @@ public function indexAction($contextNodeIdentifier, $dimensionCombination, $term return; } - $requestJson = $this->buildRequestForTerm($contextNodeIdentifier, $dimensionCombination, $term); + $requestJson = $this->buildRequestForTerm($term, $contextNodeIdentifier, $dimensionCombination); try { $response = $this->elasticSearchClient->getIndex()->request('POST', '/_search', [], $requestJson)->getTreatedContent(); @@ -99,7 +99,7 @@ public function indexAction($contextNodeIdentifier, $dimensionCombination, $term * @return ElasticSearchQueryBuilder * @throws QueryBuildingException */ - protected function buildRequestForTerm($contextNodeIdentifier, $dimensionCombination, $term) + protected function buildRequestForTerm($term, $contextNodeIdentifier, $dimensionCombination = null) { $cacheKey = $contextNodeIdentifier . '-' . md5($dimensionCombination); $termPlaceholder = '---term-soh2gufuNi---'; From 584326a50961be05088e8c577834cf27dbf0112f Mon Sep 17 00:00:00 2001 From: Aske Ertmann Date: Thu, 13 Sep 2018 13:16:08 +0200 Subject: [PATCH 2/4] BUGFIX: Don't require dimensionsCombination in suggest controller --- Classes/Controller/SuggestController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Controller/SuggestController.php b/Classes/Controller/SuggestController.php index be04a86..ca25929 100644 --- a/Classes/Controller/SuggestController.php +++ b/Classes/Controller/SuggestController.php @@ -62,7 +62,7 @@ public function initializeObject() * @return void * @throws QueryBuildingException */ - public function indexAction($term, $contextNodeIdentifier, $dimensionCombination) + public function indexAction($term, $contextNodeIdentifier, $dimensionCombination = null) { if ($this->elasticSearchClient === null) { throw new \RuntimeException('The SuggestController needs an ElasticSearchClient, it seems you run without the flowpack/elasticsearch-contentrepositoryadaptor package, though.', 1487189823); @@ -109,8 +109,8 @@ protected function buildRequestForTerm($term, $contextNodeIdentifier, $dimension // and the term is trimmed to alnum characters to avoid errors $suggestTerm = preg_replace('/[[:^alnum:]]/', '', explode(' ', $term)[0]); - if(!$this->elasticSearchQueryTemplateCache->has($cacheKey)) { - $contentContext = $this->createContentContext('live', json_decode($dimensionCombination, true)); + if (!$this->elasticSearchQueryTemplateCache->has($cacheKey)) { + $contentContext = $this->createContentContext('live', $dimensionCombination ? json_decode($dimensionCombination, true) : []); $contextNode = $contentContext->getNodeByIdentifier($contextNodeIdentifier); /** @var ElasticSearchQueryBuilder $query */ From 139db78088f3fc8c9d30a48573cf0c0849ce2f82 Mon Sep 17 00:00:00 2001 From: Aske Ertmann Date: Thu, 13 Sep 2018 13:16:32 +0200 Subject: [PATCH 3/4] TASK: Output exception message when suggest query fails --- Classes/Controller/SuggestController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Controller/SuggestController.php b/Classes/Controller/SuggestController.php index ca25929..125b3a4 100644 --- a/Classes/Controller/SuggestController.php +++ b/Classes/Controller/SuggestController.php @@ -86,7 +86,7 @@ public function indexAction($term, $contextNodeIdentifier, $dimensionCombination $result['completions'] = $this->extractCompletions($response); $result['suggestions'] = $this->extractSuggestions($response); } catch (\Exception $e) { - $result['errors'] = ['Could not execute query']; + $result['errors'] = ['Could not execute query: ' . $e->getMessage()]; } $this->view->assign('value', $result); From 40f7c4d2a024940f7fd14102c15b8b99c7968b16 Mon Sep 17 00:00:00 2001 From: Aske Ertmann Date: Thu, 13 Sep 2018 13:17:18 +0200 Subject: [PATCH 4/4] TASK: Adjust search completions and suggestions to ES 5.x --- Classes/Controller/SuggestController.php | 2 +- Classes/EelHelper/SuggestionIndexHelper.php | 13 +---- Configuration/NodeTypes.Mixins.yaml | 17 +++--- README.md | 62 +++++++++++++++++---- 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/Classes/Controller/SuggestController.php b/Classes/Controller/SuggestController.php index 125b3a4..a94c260 100644 --- a/Classes/Controller/SuggestController.php +++ b/Classes/Controller/SuggestController.php @@ -132,7 +132,7 @@ protected function buildRequestForTerm($term, $contextNodeIdentifier, $dimension ] ]) ->suggestions('suggestions', [ - 'text' => $termPlaceholder, + 'prefix' => $termPlaceholder, 'completion' => [ 'field' => '__suggestions', 'fuzzy' => true, diff --git a/Classes/EelHelper/SuggestionIndexHelper.php b/Classes/EelHelper/SuggestionIndexHelper.php index cfb3258..b01ef09 100644 --- a/Classes/EelHelper/SuggestionIndexHelper.php +++ b/Classes/EelHelper/SuggestionIndexHelper.php @@ -29,12 +29,10 @@ class SuggestionIndexHelper implements ProtectedContextAwareInterface * @param int $weight A positive integer or a string containing a positive integer, which defines a weight and allows you to rank your suggestions. * @return array */ - public function build($input, $output = '', array $payload = [], $weight = 1) + public function build($input, $weight = 1) { return [ 'input' => $this->prepareInput($input), - 'output' => $this->prepareOutput($output), - 'payload' => json_encode($payload), 'weight' => $weight ]; } @@ -66,15 +64,6 @@ protected function prepareInput($input) } } - /** - * @param string $input - * @return array - */ - protected function prepareOutput($input) - { - return strip_tags($input); - } - /** * All methods are considered safe * diff --git a/Configuration/NodeTypes.Mixins.yaml b/Configuration/NodeTypes.Mixins.yaml index b5ab420..7b435a0 100644 --- a/Configuration/NodeTypes.Mixins.yaml +++ b/Configuration/NodeTypes.Mixins.yaml @@ -5,18 +5,20 @@ search: elasticSearchMapping: type: completion - payloads: true - context: - workspace: + contexts: + - + name: 'workspace' type: category path: '__workspace' - parentPath: + - + name: 'parentPath' type: category path: '__parentPath' - dimensionCombinationHash: + - + name: 'dimensionCombinationHash' type: category path: '__dimensionCombinationHash' - indexing: "${Flowpack.SearchPlugin.Suggestion.build(q(node).property('title') ? q(node).property('title') : '', q(node).is('[instanceof Neos.Neos:Document]') ? node.identifier : q(node).parents('[instanceof Neos.Neos:Document]').get(0).identifier, {nodeIdentifier: node.identifier}, 20)}" + indexing: "${Flowpack.SearchPlugin.Suggestion.build(q(node).property('title') ? q(node).property('title') : '', 20)}" 'Flowpack.SearchPlugin:AutocompletableMixin': abstract: true @@ -24,6 +26,7 @@ '__completion': search: elasticSearchMapping: - type: string + type: text analyzer: autocomplete + fielddata: true indexing: "${String.stripTags(q(node).property('title'))}" diff --git a/README.md b/README.md index 6264721..6557cc3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This plugin is a Search Plugin, to be used together with -* [Flowpack.ElasticSearch.ContentRepositoryAdaptor](https://github.com/Flowpack/Flowpack.ElasticSearch.ContentRepositoryAdaptor) or +* [Flowpack.ElasticSearch.ContentRepositoryAdaptor](https://github.com/Flowpack/Flowpack.ElasticSearch.ContentRepositoryAdaptor) or * [Flowpack.SimpleSearch.ContentRepositoryAdaptor](https://github.com/Flowpack/Flowpack.SimpleSearch.ContentRepositoryAdaptor). ## Installation @@ -34,7 +34,7 @@ To specify a custom index name, the following is needed: elasticSearch: indexName: acmecom -### Pagination +### Pagination The pagination search results can be configured via Fusion. The following shows the defaults: @@ -58,7 +58,7 @@ Feel free to use the `DocumentSearchResult.html` in the Flowpack.SearchPlugin as ## Search completions and suggestions -The default search form template comes with a `data-autocomplete-source` attribute pointing to the +The default search form template comes with a `data-autocomplete-source` attribute pointing to the `SuggestController` of this package. To use this term suggester, you need to configure the indexing like this, to define a custom @@ -89,12 +89,12 @@ done like this: superTypes: 'Flowpack.SearchPlugin:SuggestableMixin': true 'Flowpack.SearchPlugin:AutocompletableMixin': true - + 'Neos.Neos:Shortcut': superTypes: 'Flowpack.SearchPlugin:SuggestableMixin': false 'Flowpack.SearchPlugin:AutocompletableMixin': false - + 'Neos.NodeTypes:TitleMixin': superTypes: 'Flowpack.SearchPlugin:SuggestableMixin': true @@ -124,23 +124,65 @@ The returned JSON looks like this (with a `term` of "content" after indexing the "suggestions": [ { "text": "995c9174-ddd6-4d5c-cfc0-1ffc82184677", - "score": 20, + "_index": "acmecom-1536833562", + "_type": "Neos-Neos:Page", + "_id": "03da089f6495852dc9e7b796adde85f21093b3c7", + "score": 40, "payload": { - "nodeIdentifier": "d17caff2-f50c-d30b-b735-9b9216de02e9" + "__path": "/sites/acmecom/node-2" + }, + "contexts": { + "workspace": { + 0: "live" + }, + "parentPath": { + 0: "/sites/acmecom" + }, + "dimensionCombinationHash": { + 0: "d751713988987e9331980363e24189ce" + }, } }, { "text": "a66ec7db-3459-b67b-7bcb-16e2508a89f0", + "_index": "acmecom-1536833562", + "_type": "Neos-Neos:Page", + "_id": "151a1d0531f1ac5c1a267a3d6a3af84967e0c35f", "score": 20, "payload": { - "nodeIdentifier": "fd283257-9b12-8412-f922-6643ac818294" + "__path": "/sites/acmecom/node-1" + }, + "contexts": { + "workspace": { + 0: "live" + }, + "parentPath": { + 0: "/sites/acmecom" + }, + "dimensionCombinationHash": { + 0: "d751713988987e9331980363e24189ce" + }, } }, { "text": "a3474e1d-dd60-4a84-82b1-18d2f21891a3", + "_index": "acmecom-1536833562", + "_id": "c443d53c76de1af2438b8af0bf33dc7befe291f5", + "_type": "Neos-Neos:Page", "score": 20, - "payload": { - "nodeIdentifier": "7eee2ee6-2a4e-5240-3674-2fb84a51900b" + "_source": { + "__path": "/sites/acmecom/node-3" + }, + "contexts": { + "workspace": { + 0: "live" + }, + "parentPath": { + 0: "/sites/acmecom" + }, + "dimensionCombinationHash": { + 0: "d751713988987e9331980363e24189ce" + }, } } ]