From 9108553f09c0c4e3dd29fd7b0612671b6014001b Mon Sep 17 00:00:00 2001 From: Daniel Klabbers Date: Thu, 6 Jan 2022 12:58:50 +0100 Subject: [PATCH] add and vs or distinction, but partial isnt working in combination with the others yet --- src/Api/Controllers/SearchController.php | 30 ++++++++++++++---------- src/Elasticsearch/MatchQuery.php | 16 +++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/Api/Controllers/SearchController.php b/src/Api/Controllers/SearchController.php index 3d0ee4f..453045b 100644 --- a/src/Api/Controllers/SearchController.php +++ b/src/Api/Controllers/SearchController.php @@ -4,8 +4,6 @@ namespace Blomstra\Search\Api\Controllers; use Blomstra\Search\Elasticsearch\MatchPhraseQuery; use Blomstra\Search\Elasticsearch\MatchQuery; -use Blomstra\Search\Elasticsearch\SimpleSearchQuery; -use Blomstra\Search\Elasticsearch\WildcardQuery; use Blomstra\Search\Save\Document as ElasticDocument; use Blomstra\Search\Elasticsearch\TermsQuery; use Elasticsearch\Client; @@ -59,8 +57,9 @@ class SearchController extends ListDiscussionsController if (! empty($search)) { $filterQuery ->add($this->sentenceMatch($search)) - ->add($this->wordMatch($search)) - ->add($this->partialMatch($search)) + ->add($this->wordMatch($search, 'and')) + ->add($this->wordMatch($search, 'or')) +// ->add($this->partialMatch($search)) ; } @@ -202,59 +201,66 @@ class SearchController extends ListDiscussionsController protected function sentenceMatch(string $q): Query { + $query = (new MatchPhraseQuery('content', $q)); + return BoolQuery::create() // Discussion titles ->add( BoolQuery::create() ->add(TermQuery::create('type', 'discussions'), 'filter') - ->add((new MatchPhraseQuery('content', $q))->boost(1)), + ->add($query->boost(1)), 'should' ) // Post bodies ->add( BoolQuery::create() ->add(TermQuery::create('type', 'posts'), 'filter') - ->add((new MatchPhraseQuery('content', $q))->boost(.9)), + ->add($query->boost(.9)), 'should' ); } - protected function wordMatch(string $q) + protected function wordMatch(string $q, string $operator = 'or') { + $query = (new MatchQuery('content', $q)) + ->operator($operator); + + $boost = $operator === 'and' ? 1 : .5; + return BoolQuery::create() // Discussion titles ->add( BoolQuery::create() ->add(TermQuery::create('type', 'discussions'), 'filter') - ->add((new MatchQuery('content', $q))->boost(.6)), + ->add($query->boost($boost * .6)), 'should' ) // Post bodies ->add( BoolQuery::create() ->add(TermQuery::create('type', 'posts'), 'filter') - ->add((new MatchQuery('content', $q))->boost(.5)), + ->add($query->boost($boost * .5)), 'should' ); } protected function partialMatch(string $q) { - $wildcard = (new MatchQuery('content_partial', $q)); + $query = (new MatchQuery('content_partial', $q)); return BoolQuery::create() // Discussion titles ->add( BoolQuery::create() ->add(TermQuery::create('type', 'discussions'), 'filter') - ->add($wildcard->boost(.3)), + ->add($query->boost(.3)), 'should' ) // Post bodies ->add( BoolQuery::create() ->add(TermQuery::create('type', 'posts'), 'filter') - ->add($wildcard->boost(.2)), + ->add($query->boost(.2)), 'should' ); } diff --git a/src/Elasticsearch/MatchQuery.php b/src/Elasticsearch/MatchQuery.php index 40d60d2..21cc07b 100644 --- a/src/Elasticsearch/MatchQuery.php +++ b/src/Elasticsearch/MatchQuery.php @@ -7,6 +7,7 @@ class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery protected string $operator = 'or'; protected float $boost = 1; protected ?string $analyzer = null; + protected bool $zeroTerms = false; public function and() { @@ -15,6 +16,13 @@ class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery return $this; } + public function operator(string $operator) + { + $this->operator = $operator; + + return $this; + } + public function boost(float $boost = 1) { $this->boost = $boost; @@ -29,12 +37,20 @@ class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery return $this; } + public function zeroTerms(bool $zeroTerms = true) + { + $this->zeroTerms = $zeroTerms; + + return $this; + } + public function toArray(): array { $query = parent::toArray(); $query['match'][$this->field]['operator'] = $this->operator; $query['match'][$this->field]['boost'] = $this->boost; + $query['match'][$this->field]['zero_terms_query'] = $this->zeroTerms ? 'all' : 'none'; return $query; }