/** * Builds a Mapping collection from the annotation sources that are present * * @throws \Flowpack\ElasticSearch\Exception * @return \Flowpack\ElasticSearch\Mapping\MappingCollection<\Flowpack\ElasticSearch\Domain\Model\Mapping> */ public function buildMappingInformation() { if (!$this->client instanceof Model\Client) { throw new \Flowpack\ElasticSearch\Exception('No client was given for mapping retrieval. Set a client BackendMappingBuilder->setClient().', 1339678111); } $this->indicesWithoutTypeInformation = array(); $response = $this->client->request('GET', '/_mapping'); $mappingInformation = new MappingCollection(MappingCollection::TYPE_BACKEND); $mappingInformation->setClient($this->client); $indexNames = $this->indexInformer->getAllIndexNames(); foreach ($response->getTreatedContent() as $indexName => $indexSettings) { if (!in_array($indexName, $indexNames)) { continue; } $index = new Model\Index($indexName); if (empty($indexSettings)) { $this->indicesWithoutTypeInformation[] = $indexName; } foreach ($indexSettings as $typeName => $typeSettings) { $type = new Model\GenericType($index, $typeName); $mapping = new Model\Mapping($type); if (isset($typeSettings['properties'])) { foreach ($typeSettings['properties'] as $propertyName => $propertySettings) { foreach ($propertySettings as $key => $value) { $mapping->setPropertyByPath(array($propertyName, $key), $value); } } } $mappingInformation->add($mapping); } } return $mappingInformation; }
/** * Tells whether a member of this collection has a specific index/type/property settings value * * @param \Flowpack\ElasticSearch\Domain\Model\Mapping $inquirerMapping * @param string $propertyName * @param $settingKey * * @return mixed */ public function getMappingSetting(\Flowpack\ElasticSearch\Domain\Model\Mapping $inquirerMapping, $propertyName, $settingKey) { foreach ($this as $memberMapping) { /** @var $memberMapping \Flowpack\ElasticSearch\Domain\Model\Mapping */ if ($inquirerMapping->getType()->getName() === $memberMapping->getType()->getName() && $inquirerMapping->getType()->getIndex()->getName() === $memberMapping->getType()->getIndex()->getName()) { return $memberMapping->getPropertyByPath(array($propertyName, $settingKey)); } } return NULL; }
/** * Builds a Mapping Collection from the configured node types * * @param \Flowpack\ElasticSearch\Domain\Model\Index $index * @return \Flowpack\ElasticSearch\Mapping\MappingCollection<\Flowpack\ElasticSearch\Domain\Model\Mapping> */ public function buildMappingInformation(Index $index) { $this->lastMappingErrors = new \TYPO3\Flow\Error\Result(); $mappings = new MappingCollection(MappingCollection::TYPE_ENTITY); /** @var NodeType $nodeType */ foreach ($this->nodeTypeManager->getNodeTypes() as $nodeTypeName => $nodeType) { if ($nodeTypeName === 'unstructured' || $nodeType->isAbstract()) { continue; } $type = $index->findType(self::convertNodeTypeNameToMappingName($nodeTypeName)); $mapping = new Mapping($type); // http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-root-object-type.html#_dynamic_templates // 'not_analyzed' is necessary $mapping->addDynamicTemplate('dimensions', array('path_match' => '__dimensionCombinations.*', 'match_mapping_type' => 'string', 'mapping' => array('type' => 'string', 'index' => 'not_analyzed'))); foreach ($nodeType->getProperties() as $propertyName => $propertyConfiguration) { if (isset($propertyConfiguration['search']) && isset($propertyConfiguration['search']['elasticSearchMapping'])) { if (is_array($propertyConfiguration['search']['elasticSearchMapping'])) { $mapping->setPropertyByPath($propertyName, $propertyConfiguration['search']['elasticSearchMapping']); } } elseif (isset($propertyConfiguration['type']) && isset($this->defaultConfigurationPerType[$propertyConfiguration['type']]['elasticSearchMapping'])) { if (is_array($this->defaultConfigurationPerType[$propertyConfiguration['type']]['elasticSearchMapping'])) { $mapping->setPropertyByPath($propertyName, $this->defaultConfigurationPerType[$propertyConfiguration['type']]['elasticSearchMapping']); } } else { $this->lastMappingErrors->addWarning(new \TYPO3\Flow\Error\Warning('Node Type "' . $nodeTypeName . '" - property "' . $propertyName . '": No ElasticSearch Mapping found.')); } } $mappings->add($mapping); } return $mappings; }
/** * @param Mapping $mapping * @param string $className * @param string $propertyName * * @throws \Flowpack\ElasticSearch\Exception * @return void */ protected function augmentMappingByProperty(Mapping $mapping, $className, $propertyName) { list($propertyType) = $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var'); if (($transformAnnotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, 'Flowpack\\ElasticSearch\\Annotations\\Transform')) !== NULL) { $mappingType = $this->transformerFactory->create($transformAnnotation->type)->getTargetMappingType(); } elseif (\TYPO3\Flow\Utility\TypeHandling::isSimpleType($propertyType)) { $mappingType = $propertyType; } elseif ($propertyType === '\\DateTime') { $mappingType = 'date'; } else { throw new \Flowpack\ElasticSearch\Exception('Mapping is only supported for simple types and DateTime objects; "' . $propertyType . '" given but without a Transform directive.'); } $mapping->setPropertyByPath($propertyName, array('type' => $mappingType)); $annotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, 'Flowpack\\ElasticSearch\\Annotations\\Mapping'); if ($annotation instanceof MappingAnnotation) { $mapping->setPropertyByPath($propertyName, $this->processMappingAnnotation($annotation, $mapping->getPropertyByPath($propertyName))); if ($annotation->getFields()) { foreach ($annotation->getFields() as $multiFieldAnnotation) { $multiFieldIndexName = trim($multiFieldAnnotation->index_name); if ($multiFieldIndexName === '') { throw new \Flowpack\ElasticSearch\Exception('Multi field require an unique index name "' . $className . '::' . $propertyName . '".'); } if (isset($multiFields[$multiFieldIndexName])) { throw new \Flowpack\ElasticSearch\Exception('Duplicate index name in the same multi field is not allowed "' . $className . '::' . $propertyName . '".'); } $multiFieldAnnotation->type = $mappingType; $multiFields[$multiFieldIndexName] = $this->processMappingAnnotation($multiFieldAnnotation); } $mapping->setPropertyByPath(array($propertyName, 'fields'), $multiFields); } } }