From d7db6cba44f27acf65aec484f2bd066821745d17 Mon Sep 17 00:00:00 2001 From: andrii-pukhalevych Date: Thu, 20 Aug 2026 23:04:32 +0300 Subject: [PATCH 1/2] Make ResultSet serializable so cached queries can be executed --- src/ResultSet.php | 36 ++++++++++++++++++++++++++++++++++++ tests/TestCase/QueryTest.php | 21 +++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/ResultSet.php b/src/ResultSet.php index 151c190..e109f12 100644 --- a/src/ResultSet.php +++ b/src/ResultSet.php @@ -236,6 +236,42 @@ public function current(): Document return $entity; } + /** + * Returns the state to be serialized, so result sets can be stored in a cache (without elastica handles) + * + * @return array + */ + public function __serialize(): array + { + return [ + 'resultSet' => $this->resultSet, + 'entityClass' => $this->entityClass, + 'embeds' => $this->embeds, + 'repoName' => $this->repoName, + ]; + } + + /** + * Restores a result set from its serialized state + * + * @param array $data The state as returned by __serialize() + * @return void + */ + public function __unserialize(array $data): void + { + assert($data['resultSet'] instanceof ElasticaResultSet); + assert(is_string($data['entityClass'])); + assert(is_array($data['embeds'])); + assert(is_string($data['repoName'])); + + $this->resultSet = $data['resultSet']; + $this->entityClass = $data['entityClass']; + $this->embeds = $data['embeds']; + $this->repoName = $data['repoName']; + + parent::__construct($this->resultSet); + } + /** * Debug output hook method. */ diff --git a/tests/TestCase/QueryTest.php b/tests/TestCase/QueryTest.php index 90518a9..90e8f12 100644 --- a/tests/TestCase/QueryTest.php +++ b/tests/TestCase/QueryTest.php @@ -17,6 +17,8 @@ namespace Cake\ElasticSearch\Test\TestCase; use AssertionError; +use Cake\Cache\Cache; +use Cake\Cache\Engine\FileEngine; use Cake\Datasource\ConnectionManager; use Cake\Datasource\Exception\RecordNotFoundException; use Cake\Datasource\RepositoryInterface; @@ -682,6 +684,25 @@ public function testCacheMethod(): void $this->assertSame($query, $result); } + /** + * Test that a cached query stores its results when it is executed and reads them back on the next execution + */ + public function testCacheMethodWithExecutedQuery(): void + { + Cache::setConfig('query_cache', [ + 'className' => FileEngine::class, + 'path' => sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'query_cache' . DIRECTORY_SEPARATOR, + 'duration' => '1 second', + ]); + + $index = $this->getIndex(); + $query = new Query($index); + + $results = $query->limit(1)->cache('test_key', 'query_cache')->all(); + $cached = $query->limit(1)->cache('test_key', 'query_cache')->all(); + $this->assertEquals($results->toArray(), $cached->toArray()); + } + /** * Test mapReduce method */ From b07796c580d6d943bc516100e59e15187465e618 Mon Sep 17 00:00:00 2001 From: andrii-pukhalevych Date: Thu, 20 Aug 2026 23:35:22 +0300 Subject: [PATCH 2/2] Make ResultSet serializable so cached queries can be executed --- tests/TestCase/QueryTest.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/TestCase/QueryTest.php b/tests/TestCase/QueryTest.php index 90e8f12..e203651 100644 --- a/tests/TestCase/QueryTest.php +++ b/tests/TestCase/QueryTest.php @@ -696,11 +696,16 @@ public function testCacheMethodWithExecutedQuery(): void ]); $index = $this->getIndex(); - $query = new Query($index); - $results = $query->limit(1)->cache('test_key', 'query_cache')->all(); - $cached = $query->limit(1)->cache('test_key', 'query_cache')->all(); + $results = (new Query($index))->limit(1)->cache('test_key', 'query_cache')->all(); + $cached = (new Query($index))->limit(1)->cache('test_key', 'query_cache')->all(); $this->assertEquals($results->toArray(), $cached->toArray()); + $this->assertEquals($results->getTotalHits(), $cached->getTotalHits()); + $this->assertEquals($results->getAggregations(), $cached->getAggregations()); + $this->assertEquals($results->getSuggests(), $cached->getSuggests()); + $this->assertEquals($results->getMaxScore(), $cached->getMaxScore()); + $this->assertEquals($results->getTotalTime(), $cached->getTotalTime()); + $this->assertEquals($results->hasTimedOut(), $cached->hasTimedOut()); } /**