From f475bb878f30d1f465c66d627b41ced56e309ecd Mon Sep 17 00:00:00 2001 From: Evgenij Manoylin Date: Tue, 11 Feb 2025 11:49:59 +0300 Subject: [PATCH 1/4] IDBPR-2554 Add whereMoreLikeThis and addFunctionScore --- src/Concerns/DecoratesBoolQuery.php | 22 +++++++++++ src/Contracts/BoostMode.php | 25 +++++++++++++ src/Contracts/FunctionScoreOptions.php | 31 ++++++++++++++++ src/Contracts/MoreLikeOptions.php | 30 +++++++++++++++ src/Contracts/ScoreMode.php | 25 +++++++++++++ src/Filtering/BoolQueryBuilder.php | 24 ++++++++++++ src/Filtering/Criterias/FunctionScore.php | 37 +++++++++++++++++++ src/Filtering/Criterias/FunctionScoreItem.php | 22 +++++++++++ src/Filtering/Criterias/MoreLike.php | 34 +++++++++++++++++ src/Filtering/Criterias/MoreLikeThis.php | 32 ++++++++++++++++ 10 files changed, 282 insertions(+) create mode 100644 src/Contracts/BoostMode.php create mode 100644 src/Contracts/FunctionScoreOptions.php create mode 100644 src/Contracts/MoreLikeOptions.php create mode 100644 src/Contracts/ScoreMode.php create mode 100644 src/Filtering/Criterias/FunctionScore.php create mode 100644 src/Filtering/Criterias/FunctionScoreItem.php create mode 100644 src/Filtering/Criterias/MoreLike.php create mode 100644 src/Filtering/Criterias/MoreLikeThis.php diff --git a/src/Concerns/DecoratesBoolQuery.php b/src/Concerns/DecoratesBoolQuery.php index a6331e4..c61ea12 100644 --- a/src/Concerns/DecoratesBoolQuery.php +++ b/src/Concerns/DecoratesBoolQuery.php @@ -3,10 +3,14 @@ namespace Ensi\LaravelElasticQuery\Concerns; use Closure; +use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use Ensi\LaravelElasticQuery\Contracts\MatchOptions; +use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; use Ensi\LaravelElasticQuery\Contracts\MultiMatchOptions; use Ensi\LaravelElasticQuery\Contracts\WildcardOptions; use Ensi\LaravelElasticQuery\Filtering\BoolQueryBuilder; +use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; +use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Traits\ForwardsCalls; @@ -141,4 +145,22 @@ public function addMustBool(callable $fn): static return $this; } + + public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLikeOptions $options = null): static + { + $this->forwardCallTo($this->boolQuery(), __FUNCTION__, func_get_args()); + + return $this; + } + + /** + * @param array $functions + * @param ?FunctionScoreOptions $options + */ + public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static + { + $this->forwardCallTo($this->boolQuery(), __FUNCTION__, func_get_args()); + + return $this; + } } diff --git a/src/Contracts/BoostMode.php b/src/Contracts/BoostMode.php new file mode 100644 index 0000000..dce33f6 --- /dev/null +++ b/src/Contracts/BoostMode.php @@ -0,0 +1,25 @@ + $scoreMode, + 'boost_mode' => $boostMode, + ])); + } + + public function toArray(): array + { + return $this->options; + } +} diff --git a/src/Contracts/MoreLikeOptions.php b/src/Contracts/MoreLikeOptions.php new file mode 100644 index 0000000..c7fbe3e --- /dev/null +++ b/src/Contracts/MoreLikeOptions.php @@ -0,0 +1,30 @@ + $minTermFreq, + 'max_query_terms' => $maxQueryTerms, + 'minimum_should_match' => $minimumShouldMatch, + ])); + } + + public function toArray(): array + { + return $this->options; + } +} diff --git a/src/Contracts/ScoreMode.php b/src/Contracts/ScoreMode.php new file mode 100644 index 0000000..d987dbf --- /dev/null +++ b/src/Contracts/ScoreMode.php @@ -0,0 +1,25 @@ +absolutePath($field), $query, $options ?: new WildcardOptions()); } + public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLikeOptions $options = null): static + { + $this->must->add(new MoreLike($fields, $likeThis, $options)); + + return $this; + } + + /** + * @param array $functions + * @param ?FunctionScoreOptions $options + */ + public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static + { + $this->should->add(new FunctionScore($functions, $options)); + + return $this; + } + public function addMustBool(callable $fn): static { $this->must->add(static::make(builder: $fn)); diff --git a/src/Filtering/Criterias/FunctionScore.php b/src/Filtering/Criterias/FunctionScore.php new file mode 100644 index 0000000..eb6b607 --- /dev/null +++ b/src/Filtering/Criterias/FunctionScore.php @@ -0,0 +1,37 @@ + $functions + * @param FunctionScoreOptions|null $options + */ + public function __construct( + private array $functions, + private ?FunctionScoreOptions $options = null, + ) { + array_map(fn ($function) => Assert::isInstanceOfAny($function, [FunctionScoreItem::class]), $functions); + } + + public function toDSL(): array + { + $body = [ + 'query' => ['match_all' => new stdClass()], + 'functions' => array_map(fn (FunctionScoreItem $function) => $function->toDSL(), $this->functions), + ]; + + if ($this->options) { + $body = array_merge($this->options->toArray(), $body); + } + + return ['function_score' => $body]; + } +} diff --git a/src/Filtering/Criterias/FunctionScoreItem.php b/src/Filtering/Criterias/FunctionScoreItem.php new file mode 100644 index 0000000..447b89e --- /dev/null +++ b/src/Filtering/Criterias/FunctionScoreItem.php @@ -0,0 +1,22 @@ + $this->weight, + 'filter' => $this->filter->toDSL(), + ]; + } +} diff --git a/src/Filtering/Criterias/MoreLike.php b/src/Filtering/Criterias/MoreLike.php new file mode 100644 index 0000000..707b5f7 --- /dev/null +++ b/src/Filtering/Criterias/MoreLike.php @@ -0,0 +1,34 @@ + $this->fields, + 'like' => $this->likeThis->toDSL(), + ]; + + if ($this->options) { + $body = array_merge($this->options->toArray(), $body); + } + + return ['more_like_this' => $body]; + } +} diff --git a/src/Filtering/Criterias/MoreLikeThis.php b/src/Filtering/Criterias/MoreLikeThis.php new file mode 100644 index 0000000..dd79a9a --- /dev/null +++ b/src/Filtering/Criterias/MoreLikeThis.php @@ -0,0 +1,32 @@ +this[] = array_filter([ + '_id' => $id, + '_index' => $index, + ]); + + return $this; + } + + public function addString(string $token): static + { + $this->this[] = $token; + + return $this; + } + + public function toDSL(): array + { + return $this->this; + } +} From b42f8a4fc3ee1262b4737def8a96f3b983301650 Mon Sep 17 00:00:00 2001 From: egmanoylin Date: Tue, 11 Feb 2025 08:50:20 +0000 Subject: [PATCH 2/4] Fix styling --- src/Filtering/BoolQueryBuilder.php | 4 ++-- src/Filtering/Criterias/FunctionScore.php | 1 - src/Filtering/Criterias/MoreLike.php | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Filtering/BoolQueryBuilder.php b/src/Filtering/BoolQueryBuilder.php index 0f1bd8d..a70bfc9 100644 --- a/src/Filtering/BoolQueryBuilder.php +++ b/src/Filtering/BoolQueryBuilder.php @@ -11,11 +11,11 @@ use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; use Ensi\LaravelElasticQuery\Contracts\MultiMatchOptions; use Ensi\LaravelElasticQuery\Contracts\WildcardOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; -use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Ensi\LaravelElasticQuery\Filtering\Criterias\Exists; use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScore; +use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLike; +use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Ensi\LaravelElasticQuery\Filtering\Criterias\MultiMatch; use Ensi\LaravelElasticQuery\Filtering\Criterias\Nested; use Ensi\LaravelElasticQuery\Filtering\Criterias\OneMatch; diff --git a/src/Filtering/Criterias/FunctionScore.php b/src/Filtering/Criterias/FunctionScore.php index eb6b607..d5c00bc 100644 --- a/src/Filtering/Criterias/FunctionScore.php +++ b/src/Filtering/Criterias/FunctionScore.php @@ -4,7 +4,6 @@ use Ensi\LaravelElasticQuery\Contracts\Criteria; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; use stdClass; use Webmozart\Assert\Assert; diff --git a/src/Filtering/Criterias/MoreLike.php b/src/Filtering/Criterias/MoreLike.php index 707b5f7..64b14c9 100644 --- a/src/Filtering/Criterias/MoreLike.php +++ b/src/Filtering/Criterias/MoreLike.php @@ -4,7 +4,6 @@ use Ensi\LaravelElasticQuery\Contracts\Criteria; use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Webmozart\Assert\Assert; class MoreLike implements Criteria From b0e91d9e6666a97ff9e1cbb9e00154eb33df3521 Mon Sep 17 00:00:00 2001 From: Evgenij Manoylin Date: Tue, 11 Feb 2025 14:49:49 +0300 Subject: [PATCH 3/4] =?UTF-8?q?IDBPR-2554=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Concerns/DecoratesBoolQuery.php | 4 +- src/Contracts/BoolQuery.php | 8 +++ .../FunctionScoreItem.php | 8 +-- src/Contracts/FunctionScoreOptions.php | 4 +- src/Contracts/MoreLikeOptions.php | 16 ++++- .../Criterias => Contracts}/MoreLikeThis.php | 8 +-- src/Filtering/BoolQueryBuilder.php | 4 +- src/Filtering/Criterias/FunctionScore.php | 4 +- src/Filtering/Criterias/MoreLike.php | 4 +- .../Search/SearchQueryIntegrationTest.php | 59 +++++++++++++++++++ 10 files changed, 99 insertions(+), 20 deletions(-) rename src/{Filtering/Criterias => Contracts}/FunctionScoreItem.php (57%) rename src/{Filtering/Criterias => Contracts}/MoreLikeThis.php (70%) diff --git a/src/Concerns/DecoratesBoolQuery.php b/src/Concerns/DecoratesBoolQuery.php index c61ea12..fd12b70 100644 --- a/src/Concerns/DecoratesBoolQuery.php +++ b/src/Concerns/DecoratesBoolQuery.php @@ -3,14 +3,14 @@ namespace Ensi\LaravelElasticQuery\Concerns; use Closure; +use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use Ensi\LaravelElasticQuery\Contracts\MatchOptions; use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; +use Ensi\LaravelElasticQuery\Contracts\MoreLikeThis; use Ensi\LaravelElasticQuery\Contracts\MultiMatchOptions; use Ensi\LaravelElasticQuery\Contracts\WildcardOptions; use Ensi\LaravelElasticQuery\Filtering\BoolQueryBuilder; -use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; -use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Traits\ForwardsCalls; diff --git a/src/Contracts/BoolQuery.php b/src/Contracts/BoolQuery.php index 9bdc776..4ab29a8 100644 --- a/src/Contracts/BoolQuery.php +++ b/src/Contracts/BoolQuery.php @@ -42,4 +42,12 @@ public function whereWildcard(string $field, string $query, ?WildcardOptions $op public function orWhereWildcard(string $field, string $query, ?WildcardOptions $options = null): static; public function addMustBool(callable $fn): static; + + public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLikeOptions $options = null): static; + + /** + * @param array $functions + * @param ?FunctionScoreOptions $options + */ + public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static; } diff --git a/src/Filtering/Criterias/FunctionScoreItem.php b/src/Contracts/FunctionScoreItem.php similarity index 57% rename from src/Filtering/Criterias/FunctionScoreItem.php rename to src/Contracts/FunctionScoreItem.php index 447b89e..836a526 100644 --- a/src/Filtering/Criterias/FunctionScoreItem.php +++ b/src/Contracts/FunctionScoreItem.php @@ -1,10 +1,10 @@ $this->weight, diff --git a/src/Contracts/FunctionScoreOptions.php b/src/Contracts/FunctionScoreOptions.php index 5d580c7..6c8176f 100644 --- a/src/Contracts/FunctionScoreOptions.php +++ b/src/Contracts/FunctionScoreOptions.php @@ -15,8 +15,8 @@ public static function make( ?string $scoreMode = null, ?string $boostMode = null, ): static { - Assert::oneOf($scoreMode, ScoreMode::cases()); - Assert::oneOf($boostMode, BoostMode::cases()); + Assert::nullOrOneOf($scoreMode, ScoreMode::cases()); + Assert::nullOrOneOf($boostMode, BoostMode::cases()); return new static(array_filter([ 'score_mode' => $scoreMode, diff --git a/src/Contracts/MoreLikeOptions.php b/src/Contracts/MoreLikeOptions.php index c7fbe3e..b7d4d61 100644 --- a/src/Contracts/MoreLikeOptions.php +++ b/src/Contracts/MoreLikeOptions.php @@ -11,14 +11,26 @@ public function __construct(private array $options = []) } public static function make( - ?int $minTermFreq = null, ?int $maxQueryTerms = null, + ?int $minTermFreq = null, + ?int $minDocFreq = null, + ?int $maxDocFreq = null, + ?int $minWordLength = null, + ?int $maxWordLength = null, + ?array $stopWords = null, + ?string $analyzer = null, ?string $minimumShouldMatch = null, ): static { return new static(array_filter([ - 'min_term_freq' => $minTermFreq, 'max_query_terms' => $maxQueryTerms, + 'min_term_freq' => $minTermFreq, + 'min_doc_freq' => $minDocFreq, + 'max_doc_freq' => $maxDocFreq, + 'min_word_length' => $minWordLength, + 'max_word_length' => $maxWordLength, + 'stop_words' => $stopWords, + 'analyzer' => $analyzer, 'minimum_should_match' => $minimumShouldMatch, ])); } diff --git a/src/Filtering/Criterias/MoreLikeThis.php b/src/Contracts/MoreLikeThis.php similarity index 70% rename from src/Filtering/Criterias/MoreLikeThis.php rename to src/Contracts/MoreLikeThis.php index dd79a9a..b6f2959 100644 --- a/src/Filtering/Criterias/MoreLikeThis.php +++ b/src/Contracts/MoreLikeThis.php @@ -1,10 +1,10 @@ this; } diff --git a/src/Filtering/BoolQueryBuilder.php b/src/Filtering/BoolQueryBuilder.php index 0f1bd8d..9239fca 100644 --- a/src/Filtering/BoolQueryBuilder.php +++ b/src/Filtering/BoolQueryBuilder.php @@ -6,13 +6,13 @@ use Ensi\LaravelElasticQuery\Concerns\SupportsPath; use Ensi\LaravelElasticQuery\Contracts\BoolQuery; use Ensi\LaravelElasticQuery\Contracts\Criteria; +use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use Ensi\LaravelElasticQuery\Contracts\MatchOptions; use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; +use Ensi\LaravelElasticQuery\Contracts\MoreLikeThis; use Ensi\LaravelElasticQuery\Contracts\MultiMatchOptions; use Ensi\LaravelElasticQuery\Contracts\WildcardOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; -use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; use Ensi\LaravelElasticQuery\Filtering\Criterias\Exists; use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScore; use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLike; diff --git a/src/Filtering/Criterias/FunctionScore.php b/src/Filtering/Criterias/FunctionScore.php index eb6b607..4b99029 100644 --- a/src/Filtering/Criterias/FunctionScore.php +++ b/src/Filtering/Criterias/FunctionScore.php @@ -3,8 +3,8 @@ namespace Ensi\LaravelElasticQuery\Filtering\Criterias; use Ensi\LaravelElasticQuery\Contracts\Criteria; +use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\FunctionScoreItem; use stdClass; use Webmozart\Assert\Assert; @@ -25,7 +25,7 @@ public function toDSL(): array { $body = [ 'query' => ['match_all' => new stdClass()], - 'functions' => array_map(fn (FunctionScoreItem $function) => $function->toDSL(), $this->functions), + 'functions' => array_map(fn (FunctionScoreItem $function) => $function->toArray(), $this->functions), ]; if ($this->options) { diff --git a/src/Filtering/Criterias/MoreLike.php b/src/Filtering/Criterias/MoreLike.php index 707b5f7..8034076 100644 --- a/src/Filtering/Criterias/MoreLike.php +++ b/src/Filtering/Criterias/MoreLike.php @@ -4,7 +4,7 @@ use Ensi\LaravelElasticQuery\Contracts\Criteria; use Ensi\LaravelElasticQuery\Contracts\MoreLikeOptions; -use Ensi\LaravelElasticQuery\Filtering\Criterias\MoreLikeThis; +use Ensi\LaravelElasticQuery\Contracts\MoreLikeThis; use Webmozart\Assert\Assert; class MoreLike implements Criteria @@ -22,7 +22,7 @@ public function toDSL(): array { $body = [ 'fields' => $this->fields, - 'like' => $this->likeThis->toDSL(), + 'like' => $this->likeThis->toArray(), ]; if ($this->options) { diff --git a/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php b/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php index 45f3b53..edeb72a 100644 --- a/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php +++ b/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php @@ -1,14 +1,23 @@ whereMoreLikeThis( + $fields, + $likeThis, + MoreLikeOptions::make( + minTermFreq: 1, + minDocFreq: 1, + ) + ) + ->get(); + + assertEqualsCanonicalizing($expectedIds, $result->pluck('_id')->all()); +})->with([ + 'array id' => [['tags'], (new MoreLikeThis())->addId('405'), ['150']], + 'array string' => [['tags'], (new MoreLikeThis())->addString('drinks'), ['150', '405']], + 'full text id' => [['description'], (new MoreLikeThis())->addId('1'), ['150', '328', '471']], + 'full text string' => [['description'], (new MoreLikeThis())->addString('description'), ['1', '150', '471']], + 'full text combine' => [['description'], (new MoreLikeThis())->addId('1')->addString('water'), ['150', '328', '405', '471']], +]); + +test('search query add function score', function () { + /** @var SearchIntegrationTestCase $this */ + + $result = ProductsIndex::query() + ->addFunctionScore( + [ + new FunctionScoreItem( + weight: 10, + filter: new Terms( + field: "tags", + values: ["drinks"], + ), + ), + ], + FunctionScoreOptions::make( + scoreMode: ScoreMode::SUM, + boostMode: BoostMode::SUM + ) + ) + ->get(); + + assertCount(6, $result); + + assertContains('drinks', $result[0]['_source']['tags']); + assertContains('drinks', $result[1]['_source']['tags']); +}); From 9ed6647c1914762de1a96c3cb75314fca00bbb14 Mon Sep 17 00:00:00 2001 From: Evgenij Manoylin Date: Tue, 11 Feb 2025 15:28:08 +0300 Subject: [PATCH 4/4] =?UTF-8?q?IDBPR-2554=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4?= =?UTF-8?q?=D0=B0=D1=87=D0=B8=20query=20=D0=B4=D0=BB=D1=8F=20function=5Fsc?= =?UTF-8?q?ore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Concerns/DecoratesBoolQuery.php | 4 +++- src/Contracts/BoolQuery.php | 3 ++- src/Filtering/BoolQueryBuilder.php | 6 ++++-- src/Filtering/Criterias/FunctionScore.php | 4 +++- .../IntegrationTests/Search/SearchQueryIntegrationTest.php | 4 ++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Concerns/DecoratesBoolQuery.php b/src/Concerns/DecoratesBoolQuery.php index fd12b70..ce04194 100644 --- a/src/Concerns/DecoratesBoolQuery.php +++ b/src/Concerns/DecoratesBoolQuery.php @@ -3,6 +3,7 @@ namespace Ensi\LaravelElasticQuery\Concerns; use Closure; +use Ensi\LaravelElasticQuery\Contracts\DSLAware; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use Ensi\LaravelElasticQuery\Contracts\MatchOptions; @@ -155,9 +156,10 @@ public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLi /** * @param array $functions + * @param ?DSLAware $query * @param ?FunctionScoreOptions $options */ - public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static + public function addFunctionScore(array $functions, ?DSLAware $query = null, ?FunctionScoreOptions $options = null): static { $this->forwardCallTo($this->boolQuery(), __FUNCTION__, func_get_args()); diff --git a/src/Contracts/BoolQuery.php b/src/Contracts/BoolQuery.php index 4ab29a8..7d3723a 100644 --- a/src/Contracts/BoolQuery.php +++ b/src/Contracts/BoolQuery.php @@ -47,7 +47,8 @@ public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLi /** * @param array $functions + * @param ?DSLAware $query * @param ?FunctionScoreOptions $options */ - public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static; + public function addFunctionScore(array $functions, ?DSLAware $query = null, ?FunctionScoreOptions $options = null): static; } diff --git a/src/Filtering/BoolQueryBuilder.php b/src/Filtering/BoolQueryBuilder.php index 9239fca..49d6daf 100644 --- a/src/Filtering/BoolQueryBuilder.php +++ b/src/Filtering/BoolQueryBuilder.php @@ -6,6 +6,7 @@ use Ensi\LaravelElasticQuery\Concerns\SupportsPath; use Ensi\LaravelElasticQuery\Contracts\BoolQuery; use Ensi\LaravelElasticQuery\Contracts\Criteria; +use Ensi\LaravelElasticQuery\Contracts\DSLAware; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use Ensi\LaravelElasticQuery\Contracts\MatchOptions; @@ -260,11 +261,12 @@ public function whereMoreLikeThis(array $fields, MoreLikeThis $likeThis, ?MoreLi /** * @param array $functions + * @param ?DSLAware $query * @param ?FunctionScoreOptions $options */ - public function addFunctionScore(array $functions, ?FunctionScoreOptions $options = null): static + public function addFunctionScore(array $functions, ?DSLAware $query = null, ?FunctionScoreOptions $options = null): static { - $this->should->add(new FunctionScore($functions, $options)); + $this->should->add(new FunctionScore($functions, $query, $options)); return $this; } diff --git a/src/Filtering/Criterias/FunctionScore.php b/src/Filtering/Criterias/FunctionScore.php index 4b99029..71f060a 100644 --- a/src/Filtering/Criterias/FunctionScore.php +++ b/src/Filtering/Criterias/FunctionScore.php @@ -3,6 +3,7 @@ namespace Ensi\LaravelElasticQuery\Filtering\Criterias; use Ensi\LaravelElasticQuery\Contracts\Criteria; +use Ensi\LaravelElasticQuery\Contracts\DSLAware; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreItem; use Ensi\LaravelElasticQuery\Contracts\FunctionScoreOptions; use stdClass; @@ -16,6 +17,7 @@ class FunctionScore implements Criteria */ public function __construct( private array $functions, + private ?DSLAware $query = null, private ?FunctionScoreOptions $options = null, ) { array_map(fn ($function) => Assert::isInstanceOfAny($function, [FunctionScoreItem::class]), $functions); @@ -24,7 +26,7 @@ public function __construct( public function toDSL(): array { $body = [ - 'query' => ['match_all' => new stdClass()], + 'query' => $this->query?->toDSL() ?? ['match_all' => new stdClass()], 'functions' => array_map(fn (FunctionScoreItem $function) => $function->toArray(), $this->functions), ]; diff --git a/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php b/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php index edeb72a..b062cc2 100644 --- a/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php +++ b/tests/IntegrationTests/Search/SearchQueryIntegrationTest.php @@ -128,7 +128,7 @@ ->whereMoreLikeThis( $fields, $likeThis, - MoreLikeOptions::make( + options: MoreLikeOptions::make( minTermFreq: 1, minDocFreq: 1, ) @@ -158,7 +158,7 @@ ), ), ], - FunctionScoreOptions::make( + options: FunctionScoreOptions::make( scoreMode: ScoreMode::SUM, boostMode: BoostMode::SUM )