From 6cb289ac9b8bb6eaf09f13d9c6c0c75c7829ede4 Mon Sep 17 00:00:00 2001 From: Piotr Rugala Date: Fri, 13 Dec 2024 20:07:50 +0700 Subject: [PATCH] Support for script fields Support for script fields --- src/Client.php | 2 +- src/ResultSetBuilder.php | 15 +++++++------ tests/ResultSetBuilderTest.php | 2 +- tests/SearchTest.php | 39 ++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/Client.php b/src/Client.php index a267350..d7b6b79 100644 --- a/src/Client.php +++ b/src/Client.php @@ -20,7 +20,7 @@ class Client extends ElasticaClient private IndexNameMapper $indexNameMapper; /** - * @see \JoliCode\Elastically\Factory::buildClient + * @see Factory::buildClient */ public function __construct($config = [], ?LoggerInterface $logger = null, ?ResultSetBuilder $resultSetBuilder = null, ?IndexNameMapper $indexNameMapper = null) { diff --git a/src/ResultSetBuilder.php b/src/ResultSetBuilder.php index 28d0831..50d670a 100644 --- a/src/ResultSetBuilder.php +++ b/src/ResultSetBuilder.php @@ -64,9 +64,9 @@ public function buildResultSet(Response $response, Query $query): ResultSet * @throws ExceptionInterface * @throws SerializerExceptionInterface */ - public function buildModelFromIndexAndData(string $indexName, $source) + public function buildModelFromIndexAndData(string $indexName, $source, $fields) { - return $this->buildModel($source, $indexName, []); + return $this->buildModel($source, $fields, $indexName, []); } /** @@ -75,7 +75,7 @@ public function buildModelFromIndexAndData(string $indexName, $source) */ public function buildModelFromDocument(ElasticaDocument $document) { - return $this->buildModel($document->getData(), $document->getIndex(), [ + return $this->buildModel($document->getData(), $document->hasFields() ? $document->getFields() : [], $document->getIndex(), [ self::DOCUMENT_KEY => $document, ]); } @@ -90,7 +90,7 @@ private function buildModelFromResult(Result $result) throw new RuntimeException('Returned index is empty. Check your "filter_path".'); } - return $this->buildModel($result->getSource(), $result->getIndex(), [ + return $this->buildModel($result->getSource(), $result->hasFields() ? $result->getFields() : [], $result->getIndex(), [ self::RESULT_KEY => $result, ]); } @@ -99,16 +99,17 @@ private function buildModelFromResult(Result $result) * @throws ExceptionInterface * @throws SerializerExceptionInterface */ - private function buildModel($source, string $indexName, array $context) + private function buildModel($source, $fields, string $indexName, array $context) { - if (!$source) { + if (!$source && !$fields) { return null; } $class = $this->indexNameMapper->getClassFromIndexName($this->indexNameMapper->getPureIndexName($indexName)); $context = array_merge($this->contextBuilder->buildContext($class), $context); + $fieldsFlat = array_map(fn ($field) => reset($field), $fields); - return $this->denormalizer->denormalize($source, $class, null, $context); + return $this->denormalizer->denormalize(array_merge($source, $fieldsFlat), $class, null, $context); } } diff --git a/tests/ResultSetBuilderTest.php b/tests/ResultSetBuilderTest.php index 7e88cf7..2125484 100644 --- a/tests/ResultSetBuilderTest.php +++ b/tests/ResultSetBuilderTest.php @@ -65,6 +65,6 @@ public function testBuildModelFromIndexAndData(): void ; $resultSetBuilder = new ResultSetBuilder($indexNameMapper, $contextBuilder, $denormalizer); - $resultSetBuilder->buildModelFromIndexAndData('indexName', ['id' => 1234]); + $resultSetBuilder->buildModelFromIndexAndData('indexName', ['id' => 1234], []); } } diff --git a/tests/SearchTest.php b/tests/SearchTest.php index 819388d..f8f08d3 100644 --- a/tests/SearchTest.php +++ b/tests/SearchTest.php @@ -15,6 +15,8 @@ use Elastica\Document as ElasticaDocument; use Elastica\Query; +use Elastica\Script\Script; +use Elastica\Script\ScriptFields; use JoliCode\Elastically\Factory; use JoliCode\Elastically\Model\Document; use JoliCode\Elastically\Result; @@ -123,6 +125,43 @@ public function testMyOwnSerializer(): void $this->assertInstanceOf(ElasticaDocument::class, $results->getDocuments()[0]); $this->assertInstanceOf(SearchTestDto::class, $results->getResults()[0]->getModel()); } + + public function testSearchWithScriptedField(): void + { + $indexName = mb_strtolower(__FUNCTION__); + + $factory = $this->getFactory(null, [ + Factory::CONFIG_INDEX_CLASS_MAPPING => [ + $indexName => SearchTestDto::class, + ], + ]); + $indexer = $factory->buildIndexer(); + $client = $factory->buildClient(); + + $dto = new SearchTestDto(); + $dto->bar = 'coucou unicorns'; + + $indexer->scheduleIndex($indexName, new Document('f', $dto)); + $indexer->flush(); + + $indexer->refresh($indexName); + + $query = Query::create('unicorns'); + $query->setSource(true); + + $scriptField = new Script('params._source.bar == \'coucou unicorns\''); + $scriptFields = new ScriptFields(); + $scriptFields->addScript('foo', $scriptField); + $query->setScriptFields($scriptFields); + $results = $client->getIndex($indexName)->search($query); + + $this->assertSame(1, $results->getTotalHits()); + + $this->assertInstanceOf(Result::class, $results->getResults()[0]); + $this->assertInstanceOf(ElasticaDocument::class, $results->getDocuments()[0]); + $this->assertInstanceOf(SearchTestDto::class, $results->getResults()[0]->getModel()); + $this->assertTrue($results->getResults()[0]->getModel()->foo); + } } class SearchTestDummySerializer implements SerializerInterface, DenormalizerInterface