From 0bd5b5b3d7869c1e64b3baf3c4e1efe68fb1ac2e Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Thu, 30 Apr 2026 22:25:36 +0200 Subject: [PATCH] fix: send search_type=query_then_fetch as a top-level param in Search::count() The `$params` literal in `Search::count()` wrapped the search-type option in a numeric-keyed sub-array: $params = [ 'body' => $query->toArray(), [self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH], ]; The upstream `Client::search()` ignores numeric-keyed sub-arrays, so the option never reached Elasticsearch. Hoist the entry to a string-keyed member of `$params` and add a functional test asserting it lands in the HTTP request's query string. --- CHANGELOG.md | 1 + src/Search.php | 2 +- tests/SearchTest.php | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e7e1579..bc046ed54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Deprecated ### Removed ### Fixed +* Fixed `Elastica\Search::count()` silently dropping the `search_type=query_then_fetch` option due to a malformed array literal that wrapped it in a numeric-keyed sub-array. ### Security diff --git a/src/Search.php b/src/Search.php index e5ef0fcfd..447942d4c 100644 --- a/src/Search.php +++ b/src/Search.php @@ -329,7 +329,7 @@ public function count($query = '', bool $fullResult = false) $params = [ 'body' => $query->toArray(), - [self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH], + self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH, ]; if ($indices = $this->getIndices()) { diff --git a/tests/SearchTest.php b/tests/SearchTest.php index 697e3bbb8..3d5f05e7a 100644 --- a/tests/SearchTest.php +++ b/tests/SearchTest.php @@ -503,6 +503,32 @@ public function testCountRequest(): void $this->assertEquals(0, $count); } + #[Group('functional')] + public function testCountSendsSearchTypeQueryThenFetch(): void + { + $client = $this->_getClient(); + $index = $client->getIndex('count_search_type_test'); + $index->create([], ['recreate' => true]); + $index->addDocument(new Document('1', ['foo' => 'bar'])); + $index->refresh(); + + $search = new Search($client); + $search->addIndex($index); + $search->count(new MatchAll()); + + $lastRequest = $client->getLastRequest(); + $this->assertNotNull($lastRequest); + + \parse_str($lastRequest->getUri()->getQuery(), $query); + + // Without the fix, the search_type option was wrapped in a numeric-keyed + // sub-array of $params and silently dropped from the request. + $this->assertSame( + Search::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH, + $query[Search::OPTION_SEARCH_TYPE] ?? null + ); + } + #[Group('functional')] public function testCountRequestGet(): void {