/**
  * Converts raw array (as returned by the Elasticsearch client) to document.
  *
  * @param array  $rawData
  * @param string $documentClass Document class in short notation (e.g. AppBundle:Product)
  *
  * @return DocumentInterface
  */
 public function convertToDocument($rawData, $documentClass)
 {
     // Get document metadata
     $metadata = $this->metadataCollector->getDocumentMetadata($documentClass);
     switch (true) {
         case isset($rawData['_source']):
             $data = $rawData['_source'];
             break;
         case isset($rawData['fields']):
             $data = array_map('reset', $rawData['fields']);
             /** Check for partial fields as well (@see https://www.elastic.co/guide/en/elasticsearch/reference/1.4/search-request-fields.html) */
             // TODO: when partial fields of nested objects are selected, partial objects should be constructed
             foreach ($data as $key => $field) {
                 if (is_array($field)) {
                     $data = array_merge($data, $field);
                     unset($data[$key]);
                 }
             }
             break;
         default:
             $data = [];
     }
     // Add special fields to data
     foreach (['_id', '_parent', '_score'] as $specialField) {
         if (isset($rawData[$specialField])) {
             $data[$specialField] = $rawData[$specialField];
         }
     }
     /** @var DocumentInterface $document */
     $className = $metadata->getClassName();
     $document = $this->assignArrayToObject($data, new $className(), $metadata->getPropertiesMetadata());
     return $document;
 }
 /**
  * Build and return a document from the data source, ready for insertion into ES
  *
  * @param int|string $id
  * @return array
  */
 public function getDocument($id)
 {
     $params = ['index' => $this->sourceIndexManager->getLiveIndex(), 'type' => $this->metadataCollector->getDocumentMetadata($this->sourceDocumentClass)->getType(), 'id' => $id];
     $doc = $this->sourceIndexManager->getConnection()->getClient()->get($params);
     $result = $doc['_source'];
     $result['_id'] = $doc['_id'];
     return $result;
 }
Пример #3
0
 /**
  * Adds a prepared document array to a bulk request for the next commit.
  * Depending on the connection autocommit mode, the update may be committed right away.
  *
  * @param string $documentClass The document class in short notation (i.e. AppBundle:Product)
  * @param array  $documentArray The document to index in ES
  */
 public function persistRaw($documentClass, array $documentArray)
 {
     $documentMetadata = $this->metadataCollector->getDocumentMetadata($documentClass);
     $this->getConnection()->addBulkOperation('index', $this->writeAlias, $documentMetadata->getType(), $documentArray);
     if ($this->getConnection()->isAutocommit()) {
         $this->getConnection()->commit();
     }
 }
Пример #4
0
 /**
  * Returns an array with the Elasticsearch indices and types to be queried,
  * based on the given document classes in short notation (AppBundle:Product)
  *
  * @param string[] $documentClasses
  * @return array
  */
 public function getTargetIndicesAndTypes(array $documentClasses)
 {
     $allDocumentClassToIndexMappings = $this->documentMetadataCollector->getDocumentClassesIndices();
     $documentClassToIndexMap = array_intersect_key($allDocumentClassToIndexMappings, array_flip($documentClasses));
     $indices = [];
     $types = [];
     foreach ($documentClassToIndexMap as $documentClass => $indexManagerName) {
         $documentMetadata = $this->documentMetadataCollector->getDocumentMetadata($documentClass);
         $indices[] = $this->indexManagerRegistry->get($indexManagerName)->getReadAlias();
         $types[] = $documentMetadata->getType();
     }
     $result = ['index' => array_unique($indices), 'type' => $types];
     return $result;
 }
 /**
  * Converts document or (nested) object to an array.
  *
  * @param ObjectInterface $object             A document or a (nested) object
  * @param array           $propertiesMetadata
  *
  * @return array
  */
 public function convertToArray(ObjectInterface $object, $propertiesMetadata = [])
 {
     if (empty($propertiesMetadata)) {
         $propertiesMetadata = $this->metadataCollector->getDocumentMetadata(get_class($object))->getPropertiesMetadata();
     }
     $array = [];
     foreach ($propertiesMetadata as $name => $propertyMetadata) {
         if ($propertyMetadata['propertyAccess'] == DocumentMetadata::PROPERTY_ACCESS_PRIVATE) {
             $value = $object->{$propertyMetadata['methods']['getter']}();
         } else {
             $value = $object->{$propertyMetadata['propertyName']};
         }
         if (isset($value)) {
             // If this is a (nested) object or a list of such
             if (array_key_exists('propertiesMetadata', $propertyMetadata)) {
                 $new = [];
                 if ($propertyMetadata['multiple']) {
                     // Verify value is traversable
                     if (!(is_array($value) || is_object($value) && $value instanceof \Traversable)) {
                         throw new \InvalidArgumentException(sprintf('Value of "%s" is not traversable, although field is set to "multiple"'));
                     }
                     foreach ($value as $item) {
                         $this->checkObjectType($item, $propertyMetadata['className']);
                         $new[] = $this->convertToArray($item, $propertyMetadata['propertiesMetadata']);
                     }
                 } else {
                     $this->checkObjectType($value, $propertyMetadata['className']);
                     $new = $this->convertToArray($value, $propertyMetadata['propertiesMetadata']);
                 }
                 $array[$name] = $new;
             } elseif ($value instanceof MLProperty) {
                 foreach ($value->getValues() as $language => $langValue) {
                     $array[$name . $this->languageSeparator . $language] = $langValue;
                 }
             } else {
                 $array[$name] = $value;
             }
         }
     }
     return $array;
 }
 /**
  * Test getting metadata for document class
  */
 public function testGetDocumentMetadata()
 {
     $this->assertInstanceOf('Sineflow\\ElasticsearchBundle\\Mapping\\DocumentMetadata', $this->metadataCollector->getDocumentMetadata('TestBundle:Foo'), 'Incorrect metadata.');
 }