From 0433cf6f819e760e385e80b57980af6ab2356a6a Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Thu, 21 May 2026 13:52:36 +0200 Subject: [PATCH 1/2] fix: scope Index::refresh() to the target index (#2313) Index::refresh() was calling indices()->refresh() without passing the index name, which the underlying elasticsearch-php client maps to `POST /_refresh` (a cluster-wide refresh) instead of the expected `POST /{index}/_refresh`. This caused calls like `$client->getIndex('my-index')->refresh()` to silently refresh every index in the cluster, hurting performance on shared clusters. Pass `['index' => $this->getName()]` so the request is correctly scoped to the current index, matching the behavior of neighboring methods (delete, exists, open, close, setSettings, analyze). Client::refreshAll() is unchanged and remains the explicit cluster-wide refresh. Refs #2313 --- CHANGELOG.md | 1 + src/Index.php | 2 +- tests/IndexTest.php | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0185c420a..d9fe6446a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Deprecated ### Removed ### Fixed +* `Elastica\Index::refresh()` now refreshes only the targeted index instead of the entire cluster (previously it issued `POST /_refresh`, now it issues `POST /{index}/_refresh`) [#2313](https://github.com/ruflin/Elastica/issues/2313) ### Security diff --git a/src/Index.php b/src/Index.php index 6d042ed52..f8dd7fe2b 100644 --- a/src/Index.php +++ b/src/Index.php @@ -470,7 +470,7 @@ public function forcemerge($args = []): Response public function refresh(): Response { return $this->_client->toElasticaResponse( - $this->_client->indices()->refresh() + $this->_client->indices()->refresh(['index' => $this->getName()]) ); } diff --git a/tests/IndexTest.php b/tests/IndexTest.php index 3021fc44f..5767e8b32 100644 --- a/tests/IndexTest.php +++ b/tests/IndexTest.php @@ -1028,4 +1028,23 @@ public function testAddDocumentWithStaleIfSeqNoFailsWithVersionConflict(): void $this->expectException(ClientResponseException::class); $index->addDocument($second); } + + #[Group('functional')] + public function testRefreshTargetsIndexAndNotCluster(): void + { + $index = $this->_createIndex(); + $client = $index->getClient(); + + $response = $index->refresh(); + + $this->assertTrue($response->isOk()); + + $lastRequest = $client->getLastRequest(); + $this->assertNotNull($lastRequest); + $this->assertSame( + \sprintf('/%s/_refresh', $index->getName()), + $lastRequest->getUri()->getPath(), + 'Index::refresh() must target the specific index, not the whole cluster' + ); + } } From 7e38040e9f58e8f6c71d3b21aac0a152ede47097 Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Fri, 22 May 2026 13:27:01 +0200 Subject: [PATCH 2/2] test: assert lastRequest is RequestInterface in refresh test Address Copilot review feedback on #2315: use assertInstanceOf with Psr\Http\Message\RequestInterface for clearer failures and stronger typing (consistent with ClientFunctionalTest::testLastRequestResponse). --- tests/IndexTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/IndexTest.php b/tests/IndexTest.php index 5767e8b32..d6d4fe158 100644 --- a/tests/IndexTest.php +++ b/tests/IndexTest.php @@ -18,6 +18,7 @@ use Elastica\Status; use Elastica\Test\Base as BaseTest; use PHPUnit\Framework\Attributes\Group; +use Psr\Http\Message\RequestInterface; /** * @internal @@ -1040,7 +1041,7 @@ public function testRefreshTargetsIndexAndNotCluster(): void $this->assertTrue($response->isOk()); $lastRequest = $client->getLastRequest(); - $this->assertNotNull($lastRequest); + $this->assertInstanceOf(RequestInterface::class, $lastRequest); $this->assertSame( \sprintf('/%s/_refresh', $index->getName()), $lastRequest->getUri()->getPath(),