Finish refactoring mapping creation

This commit is contained in:
Thibaud Fabre
2016-10-18 20:06:49 +02:00
parent 7a71886dc9
commit f2cfe93f8c
13 changed files with 552 additions and 226 deletions

View File

@@ -20,12 +20,49 @@ class ComplexFieldMapping extends FieldMapping
*/
private $children = [];
private $childKey = 'fields';
public function useAsPropertyContainer()
{
$this->childKey = 'properties';
}
public function useAsFieldContainer()
{
$this->childKey = 'fields';
}
/**
* @param FieldMapping $child
* @return FieldMapping
*/
public function addChild(FieldMapping $child)
{
$this->children[] = $child;
if (isset($this->children[$child->getName()])) {
throw new \LogicException(sprintf('There is already a "%s" multi field.', $child->getName()));
}
if ($child->getType() !== $this->getType() && $this->getType() !== self::TYPE_OBJECT) {
throw new \LogicException('Child field type must match parent type.');
}
return $this->children[$child->getName()] = $child;
}
/**
* @return RawFieldMapping
*/
public function addRawChild()
{
return $this->addChild(new RawFieldMapping($this->getType()));
}
/**
* @return bool
*/
public function hasChildren()
{
return ! empty($this->children);
}
/**
@@ -39,8 +76,18 @@ class ComplexFieldMapping extends FieldMapping
/**
* @return array
*/
public function toArray()
protected function getProperties()
{
return $this->buildArray([ ]);
if (! $this->hasChildren()) {
return [];
}
$properties = [ ];
foreach ($this->children as $name => $child) {
$properties[$name] = $child->toArray();
}
return [ $this->childKey => $properties ];
}
}

View File

@@ -11,13 +11,11 @@
namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
/**
* Class DateFieldMapping
* @package Alchemy\Phrasea\SearchEngine\Elastic\Mapping
*/
class DateFieldMapping extends FieldMapping
class DateFieldMapping extends ComplexFieldMapping
{
/**
* @var string
@@ -26,12 +24,11 @@ class DateFieldMapping extends FieldMapping
/**
* @param string $name
* @param string $type
* @param string $format
*/
public function __construct($name, $type, $format)
public function __construct($name, $format)
{
parent::__construct($name, $type);
parent::__construct($name, self::TYPE_DATE);
$this->format = $format;
}
@@ -58,8 +55,8 @@ class DateFieldMapping extends FieldMapping
/**
* @return array
*/
public function toArray()
protected function getProperties()
{
return $this->buildArray([ 'format' => $this->format ]);
return array_merge([ 'format' => $this->format ], parent::getProperties());
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of phrasea-4.0.
*
* (c) Alchemy <info@alchemy.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
class FieldToFieldMappingConverter
{
public function convertField(Field $field, array $locales)
{
if ($field->getType() === FieldMapping::TYPE_DATE) {
return new DateFieldMapping($field->getName(), FieldMapping::DATE_FORMAT_CAPTION);
}
if ($field->getType() === FieldMapping::TYPE_STRING) {
$fieldMapping = new StringFieldMapping($field->getName());
if (! $field->isFacet() && ! $field->isSearchable()) {
$fieldMapping->disableIndexing();
} else {
$fieldMapping->addChild((new StringFieldMapping('raw'))->enableRawIndexing());
$fieldMapping->addAnalyzedChildren($locales);
$fieldMapping->enableTermVectors(true);
}
return $fieldMapping;
}
return new FieldMapping($field->getName(), $field->getType());
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* This file is part of phrasea-4.0.
*
* (c) Alchemy <info@alchemy.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Tag;
class MetadataTagToFieldMappingConverter
{
public function convertTag(Tag $tag)
{
if ($tag->getType() === FieldMapping::TYPE_STRING) {
$fieldMapping = new StringFieldMapping($tag->getName());
$fieldMapping->disableAnalysis();
if ($tag->isAnalyzable()) {
$fieldMapping->addChild((new StringFieldMapping('raw'))->enableRawIndexing());
$fieldMapping->enableAnalysis();
}
return $fieldMapping;
}
return new FieldMapping($tag->getName(), $tag->getType());
}
}

View File

@@ -13,14 +13,22 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
class LocalizedFieldMapping extends FieldMapping
class RawFieldMapping extends FieldMapping
{
/**
* @param string $type
*/
public function __construct($type)
{
parent::__construct('raw', $type);
}
/**
* @return array
*/
public function toArray()
protected function getProperties()
{
return $this->buildArray([]);
return [ 'index' => 'not_analyzed' ];
}
}

View File

@@ -11,9 +11,7 @@
namespace Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
use Alchemy\Phrasea\SearchEngine\Elastic\FieldMapping;
class StringFieldMapping extends FieldMapping
class StringFieldMapping extends ComplexFieldMapping
{
/**
* @var bool
@@ -30,9 +28,57 @@ class StringFieldMapping extends FieldMapping
*/
private $searchAnalyzer = null;
/**
* @var string|null
*/
private $termVector = null;
/**
* @param string $name
*/
public function __construct($name)
{
parent::__construct($name, self::TYPE_STRING);
}
public function addAnalyzedChild($name, $analyzer)
{
$child = new self($name);
$child->setAnalyzer($analyzer);
$this->addChild($child);
return $this;
}
public function addAnalyzedChildren(array $locales)
{
$child = new StringFieldMapping('light');
$child->setAnalyzer('general_light');
$this->addChild($child);
$this->addLocalizedChildren($locales);
return $this;
}
public function addLocalizedChildren(array $locales)
{
foreach ($locales as $locale) {
/** @var StringFieldMapping $child */
$child = new StringFieldMapping($locale);
$child->setAnalyzer(sprintf('%s_full', $locale));
$this->addChild($child);
}
return $this;
}
/**
* @param string $analyzer
* @param string|null $type
* @return $this
*/
public function setAnalyzer($analyzer, $type = null)
{
@@ -56,37 +102,63 @@ class StringFieldMapping extends FieldMapping
default:
throw new \LogicException(sprintf('Invalid analyzer type "%s".', $type));
}
return $this;
}
public function disableAnalysis()
{
$this->enableAnalysis = false;
return $this;
}
public function enableAnalysis()
{
$this->enableAnalysis = true;
return $this;
}
public function enableTermVectors($applyToChildren = false)
{
$this->termVector = 'with_positions_offsets';
if ($applyToChildren) {
/** @var self $child */
foreach ($this->getChildren() as $child) {
if ($child instanceof StringFieldMapping) {
$child->enableTermVectors(false);
}
}
}
return $this;
}
/**
* @return array
*/
public function toArray()
protected function getProperties()
{
$configuration = [];
$properties = [];
if ($this->analyzer) {
$configuration['analyzer'] = $this->analyzer;
$properties['analyzer'] = $this->analyzer;
}
if ($this->searchAnalyzer) {
$configuration['search_analyzer'] = $this->searchAnalyzer;
$properties['search_analyzer'] = $this->searchAnalyzer;
}
if (! $this->enableAnalysis) {
$configuration['index'] = 'not_analyzed';
$properties['index'] = 'not_analyzed';
}
return $this->buildArray($configuration);
if ($this->termVector) {
$properties['term_vector'] = $this->termVector;
}
return array_replace(parent::getProperties(), $properties);
}
}