diff --git a/src/Processor/ForeachProcessor.php b/src/Processor/ForeachProcessor.php new file mode 100644 index 0000000000..f62881e03a --- /dev/null +++ b/src/Processor/ForeachProcessor.php @@ -0,0 +1,75 @@ + + * @author Thibaut Simon-Fine + * + * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/foreach-processor.html + */ +class ForeachProcessor extends AbstractProcessor +{ + public const DEFAULT_IGNORE_MISSING_VALUE = false; + + /** + * @param AbstractProcessor|array $processor + */ + public function __construct(string $field, $processor) + { + $this->setField($field); + + if ($processor instanceof AbstractProcessor) { + $this->setProcessor($processor); + } elseif (\is_array($processor)) { + $this->setRawProcessor($processor); + } else { + throw new \TypeError(\sprintf('Argument 2 passed to %s::__construct() must be of type %s|array, %s given.', self::class, AbstractProcessor::class, \is_object($processor) ? \get_class($processor) : \gettype($processor))); + } + } + + /** + * Set field. + * + * @return $this + */ + public function setField(string $field): self + { + return $this->setParam('field', $field); + } + + /** + * Set processor. + * + * @return $this + */ + public function setProcessor(AbstractProcessor $processor): self + { + return $this->setParam('processor', $processor); + } + + /** + * Set raw processor. + * Example : ['remove' => ['field' => 'user_agent']]. + * + * @return $this + */ + public function setRawProcessor(array $processor): self + { + return $this->setParam('processor', $processor); + } + + /** + * Set ignore_missing. Default value false. + * + * If true and field does not exist or is null, the processor quietly exits without modifying the document + * + * @return $this + */ + public function setIgnoreMissing(bool $ignoreMissing): self + { + return $this->setParam('ignore_missing', $ignoreMissing); + } +} diff --git a/tests/Processor/ForeachProcessorTest.php b/tests/Processor/ForeachProcessorTest.php new file mode 100644 index 0000000000..cc2de7850b --- /dev/null +++ b/tests/Processor/ForeachProcessorTest.php @@ -0,0 +1,125 @@ + [ + 'field' => 'field1', + 'processor' => [ + 'uppercase' => [ + 'field' => 'field2', + ], + ], + ], + ]; + + $this->assertEquals($expected, $processor->toArray()); + } + + /** + * @group unit + */ + public function testForeachRawProcessorDefault(): void + { + $subprocessor = [ + 'uppercase' => [ + 'field' => 'field2', + ], + ]; + $processor = new ForeachProcessor('field1', $subprocessor); + + $expected = [ + 'foreach' => [ + 'field' => 'field1', + 'processor' => [ + 'uppercase' => [ + 'field' => 'field2', + ], + ], + ], + ]; + + $this->assertEquals($expected, $processor->toArray()); + } + + /** + * @group unit + */ + public function testForeachProcessorIgnoreMissing(): void + { + $subprocessor = new Uppercase('field2'); + $processor = new ForeachProcessor('field1', $subprocessor); + $processor->setIgnoreMissing(true); + + $expected = [ + 'foreach' => [ + 'field' => 'field1', + 'processor' => [ + 'uppercase' => [ + 'field' => 'field2', + ], + ], + 'ignore_missing' => true, + ], + ]; + + $this->assertEquals($expected, $processor->toArray()); + } + + /** + * @group functional + */ + public function testForeachProcessor(): void + { + $subprocessor = new Uppercase('_ingest._value'); + $foreach = new ForeachProcessor('values', $subprocessor); + + $pipeline = $this->_createPipeline('my_custom_pipeline', 'pipeline for Foreach'); + $pipeline->addProcessor($foreach)->create(); + + $index = $this->_createIndex(); + $bulk = new Bulk($index->getClient()); + $bulk->setIndex($index); + + $bulk->addDocuments([ + new Document(null, ['name' => 'ruflin', 'type' => 'elastica', 'values' => ['foo', 'bar', 'baz']]), + ]); + $bulk->setRequestParam('pipeline', 'my_custom_pipeline'); + + $bulk->send(); + $index->refresh(); + + /** @var ResultSet $result */ + $result = $index->search('*'); + + $this->assertCount(1, $result->getResults()); + + foreach ($result->getResults() as $rx) { + $value = $rx->getData(); + $this->assertCount(3, $value['values']); + $this->assertEquals('FOO', $value['values'][0]); + $this->assertEquals('BAR', $value['values'][1]); + $this->assertEquals('BAZ', $value['values'][2]); + } + } +}