Skip to content

Commit d4306e3

Browse files
Katharina Puchsteinskurfuerst
authored andcommitted
FEATURE: Support .simpleQueryStringFulltext() simple query string query for fulltext search
We want to support phrase searches like `"Neos and Flow"`, where quotes mean "I want this exact phrase" (similar to many search engines). When using the .fulltext() query, this did not work, and we sometimes encountered crashes when the query string contained quotes, f.e. `"Hallo"` or `Ha"llo"`. This is because the .fulltext() query does some magic for supporting UTF8 (as it seems), namely: `trim(json_encode($searchWord, JSON_UNESCAPED_UNICODE), '"')`. This removes some quotes, but not all of them :-) The simple_query_string query of Elasticsearch exposes a query string syntax which the user is directly allowed to enter: > While its syntax is more limited than the query_string query, the simple_query_string > query does not return errors for invalid syntax. Instead, it ignores any invalid > parts of the query string. This is exactly what we want for a good search field behavior. NOTE: We created an additional method because we were unsure about breaking backwards compatibility; but we think `simpleQueryStringFulltext()` should be used almost universally as replacement for `fulltext()`, as it returns better results and does not throw exceptions..
1 parent a4612a7 commit d4306e3

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

Classes/Driver/QueryInterface.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ public function from(int $size): void;
8181
*/
8282
public function fulltext(string $searchWord, array $options = []): void;
8383

84+
/**
85+
* Match the search word against the fulltext index using the elasticsearch
86+
* [simple query string query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html)
87+
*
88+
* @param string $searchWord
89+
* @param array $options Options to configure the query_string
90+
* @return void
91+
*/
92+
public function simpleQueryStringFulltext(string $searchWord, array $options = []): void;
93+
8494
/**
8595
* Configure Result Highlighting. Only makes sense in combination with fulltext(). By default, highlighting is enabled.
8696
* It can be disabled by calling "highlight(FALSE)".

Classes/Driver/Version6/Query/FilteredQuery.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ public function fulltext(string $searchWord, array $options = []): void
6767
]);
6868
}
6969

70+
/**
71+
* {@inheritdoc}
72+
*/
73+
public function simpleQueryStringFulltext(string $searchWord, array $options = []): void
74+
{
75+
$this->appendAtPath('query.bool.must', [
76+
'simple_query_string' => array_merge(
77+
$this->queryStringParameters,
78+
$options,
79+
[ 'query' => $searchWord ]
80+
)
81+
]);
82+
}
83+
7084
/**
7185
* {@inheritdoc}
7286
*/

Classes/Eel/ElasticSearchQueryBuilder.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\ElasticSearchClient;
1919
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Exception;
2020
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Exception\QueryBuildingException;
21-
use Flowpack\ElasticSearch\Domain\Model\Index;
22-
use Flowpack\ElasticSearch\Domain\Model\Mapping;
2321
use Neos\Flow\Log\ThrowableStorageInterface;
2422
use Neos\Flow\Log\Utility\LogEnvironment;
2523
use Neos\Flow\Persistence\Exception\IllegalObjectTypeException;
@@ -668,7 +666,9 @@ public function count(): int
668666
}
669667

670668
/**
671-
* Match the searchword against the fulltext index
669+
* Match the searchword against the fulltext index.
670+
*
671+
* NOTE: Please use {@see simpleQueryStringFulltext} instead, as it is more robust.
672672
*
673673
* @param string $searchWord
674674
* @param array $options Options to configure the query_string, see https://www.elastic.co/guide/en/elasticsearch/reference/7.6/query-dsl-query-string-query.html
@@ -684,6 +684,32 @@ public function fulltext(string $searchWord, array $options = []): QueryBuilderI
684684
return $this;
685685
}
686686

687+
/**
688+
* Match the searchword against the fulltext index using the elasticsearch
689+
* [simple query string query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html).
690+
*
691+
* This method has two main benefits over {@see fulltext()}:
692+
* - Supports phrase searches like `"Neos and Flow"`, where
693+
* quotes mean "I want this exact phrase" (similar to many search engines).
694+
* - do not crash if the user does not enter a fully syntactically valid query
695+
* (invalid query parts are ignored).
696+
*
697+
* This is exactly what we want for a good search field behavior.
698+
*
699+
* @param string $searchWord
700+
* @param array $options Options to configure the query_string, see https://www.elastic.co/guide/en/elasticsearch/reference/7.6/query-dsl-query-string-query.html
701+
* @return QueryBuilderInterface
702+
* @api
703+
*/
704+
public function simpleQueryStringFulltext(string $searchWord, array $options = []): QueryBuilderInterface
705+
{
706+
// We automatically enable result highlighting when doing fulltext searches. It is up to the user to use this information or not use it.
707+
$this->request->simpleQueryStringFulltext($searchWord, $options);
708+
$this->request->highlight(150, 2);
709+
710+
return $this;
711+
}
712+
687713
/**
688714
* Adds a prefix filter to the query
689715
* See: https://www.elastic.co/guide/en/elasticsearch/reference/7.6/query-dsl-prefix-query.html

Configuration/Settings.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Flowpack:
5050
- 'aggregations'
5151
- 'suggest'
5252

53-
# Parameters for the query string query used by the fullText() operation
53+
# Parameters for the query string query used by the fullText() and simpleQueryStringFulltext() operation
5454
# See https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-multi-field
5555
# for all available parameters
5656
queryStringParameters:

0 commit comments

Comments
 (0)