예제 #1
0
 /**
  * @param string $search
  * @return ResultSet
  */
 public function search($search)
 {
     $query = new Query();
     $query->setQuery($this->getBoolQuery($search));
     $query = $this->searchManager->createQuery()->searchWith($query)->hydrateWith($this->getHydrateQuery())->setMaxResults(50);
     $this->onSearch($search, $query);
     return $query->getResult();
 }
예제 #2
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $printMapping = $output->getVerbosity() > $output::VERBOSITY_NORMAL;
     $metadataFactory = $this->searchManager->getMetadataFactory();
     /** @var ClassMetadata $class */
     foreach ($metadataFactory->getAllMetadata() as $class) {
         $output->writeln(sprintf('Entity <info>%s</info> is searchable', $class->getName()));
         if (!$printMapping) {
             continue;
         }
         $meta = (array) $class;
         unset($meta['reflFields'], $meta['reflClass']);
         $output->writeln(Dumper::toTerminal($meta));
     }
 }
예제 #3
0
파일: Query.php 프로젝트: akleiber/search
 /**
  * Execute search and hydrate results if required.
  *
  * @param integer $hydrationMode
  * @throws DoctrineSearchException
  * @return mixed
  */
 public function getResult($hydrationMode = null)
 {
     if ($hydrationMode) {
         $this->hydrationMode = $hydrationMode;
     }
     $classes = array();
     foreach ($this->entityClasses as $entityClass) {
         $classes[] = $this->sm->getClassMetadata($entityClass);
     }
     $resultSet = $this->getSearchManager()->getClient()->search($this->query, $classes);
     // TODO: abstraction of support for different result sets
     if ($resultSet instanceof Elastica\ResultSet) {
         $this->count = $resultSet->getTotalHits();
         $this->facets = $resultSet->getFacets();
         $results = $resultSet->getResults();
     } else {
         $resultClass = get_class($resultSet);
         throw new DoctrineSearchException("Unexpected result set class '{$resultClass}'");
     }
     // Return results depending on hydration mode
     if ($this->hydrationMode == self::HYDRATE_BYPASS) {
         return $resultSet;
     } elseif ($this->hydrationMode == self::HYDRATE_INTERNAL) {
         return $this->sm->getUnitOfWork()->hydrateCollection($classes, $resultSet);
     }
     // Document ids are used to lookup dbms results
     $fn = function ($result) {
         return $result->getId();
     };
     $ids = array_map($fn, $results);
     return $this->getHydrationQuery()->setParameter($this->hydrationParameter, $ids ?: null)->useResultCache($this->useResultCache, $this->cacheLifetime)->getResult($this->hydrationMode);
 }
예제 #4
0
 /**
  * Construct an entity object
  *
  * @param ClassMetadata $class
  * @param object $document
  */
 public function hydrateEntity(ClassMetadata $class, $document)
 {
     // TODO: add support for different result set types from different clients
     // perhaps by wrapping documents in a layer of abstraction
     $data = $document->getData();
     $fields = array_merge($document->hasFields() ? $document->getFields() : array(), array('_version' => $document->getVersion()));
     foreach ($fields as $name => $value) {
         if (isset($class->parameters[$name])) {
             $data[$name] = $value;
         } else {
             foreach ($class->parameters as $param => $mapping) {
                 if ($mapping->name == $name) {
                     $data[$param] = $value;
                     break;
                 }
             }
         }
     }
     $data[$class->getIdentifier()] = $document->getId();
     if (method_exists($document, 'getScore')) {
         $data['score'] = $document->getScore();
     }
     $entity = $this->sm->getSerializer()->deserialize($class->className, json_encode($data));
     if ($this->evm->hasListeners(Events::postLoad)) {
         $this->evm->dispatchEvent(Events::postLoad, new Event\LifecycleEventArgs($entity, $this->sm));
     }
     return $entity;
 }
 /**
  * Execute a direct delete by query on the associated index and type
  *
  * @param object $query
  */
 public function delete($query)
 {
     $classes = $this->getClassMetadata();
     foreach ($classes as $class) {
         $this->_sm->getClient()->removeAll($class, $query);
     }
 }
예제 #6
0
 /**
  * @param BaseElasticsearchEntity $entity
  * @param bool $refresh
  *
  * @throws \Exception
  */
 public function save($entity, $refresh = false)
 {
     $this->_sm->persist($entity);
     $this->_sm->flush($entity);
     if ($refresh) {
         $this->_sm->getClient()->refreshIndex($this->getClassMetadata()->getIndexForWrite($entity->toESDocument()));
     }
 }
예제 #7
0
 public function indexEntities(ClassMetadata $searchMeta)
 {
     foreach ($this->searchManager->getMetadataFactory()->getAllMetadata() as $otherMeta) {
         if ($searchMeta->className === $otherMeta->className) {
             continue;
         }
         if (is_subclass_of($searchMeta->className, $otherMeta->className)) {
             $this->onChildSkipped($this, $searchMeta, $otherMeta);
             return;
         }
     }
     if ($searchMeta->riverImplementation) {
         $river = $this->serviceLocator->getByType($searchMeta->riverImplementation);
     } else {
         /** @var River\DefaultEntityRiver $river */
         $river = $this->serviceLocator->createInstance('Kdyby\\DoctrineSearch\\River\\DefaultEntityRiver');
     }
     if (!$river instanceof EntityRiver) {
         throw new UnexpectedValueException('The river must implement Doctrine\\Search\\EntityRiver.');
     }
     if (property_exists($river, 'onIndexStart')) {
         $river->onIndexStart[] = function (EntityRiver $river, $paginator, ORMMetadata $class) {
             $this->onIndexStart($this, $paginator, $river, $class);
         };
     }
     if (property_exists($river, 'onItemsIndexed')) {
         $river->onItemsIndexed[] = function ($self, $entities) {
             $this->onItemsIndexed($this, $entities);
         };
     }
     if (property_exists($river, 'onIndexStats')) {
         $river->onIndexStats[] = function ($self, ORMMetadata $class, $timeToIndex, $timeToRead) {
             $this->onIndexStats($this, $class, $timeToIndex, $timeToRead);
         };
     }
     // disable logger
     $config = $this->entityManager->getConfiguration();
     $oldLogger = $config->getSQLLogger();
     $config->setSQLLogger(NULL);
     $river->transfuse($searchMeta);
     $config->setSQLLogger($oldLogger);
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $metadataFactory = $this->searchManager->getClassMetadataFactory();
     $classes = $metadataFactory->getAllMetadata();
     if ($input->getOption('drop-before')) {
         $this->schema->dropMappings($classes);
     }
     $aliases = $this->schema->createMappings($classes, TRUE);
     if ($input->getOption('init-data')) {
         $indexAliases = array();
         foreach ($aliases as $alias => $original) {
             $indexAliases[] = $alias . '=' . $original;
         }
         $exitCode = $this->getApplication()->doRun(new ArrayInput(array('elastica:pipe-entities', 'index-aliases' => $indexAliases)), $output);
         if ($exitCode !== 0) {
             return 1;
         }
     }
     $output->writeln('');
     $this->schema->createAliases($aliases);
     return 0;
 }
 /**
  * (non-PHPdoc)
  *
  * @see \Zend\ServiceManager\FactoryInterface::createService()
  *
  * @return \Doctrine\Search\SearchManager
  */
 public function createService(ServiceLocatorInterface $serviceLocator)
 {
     $this->setServiceLocator($serviceLocator);
     $config = $serviceLocator->get('Config');
     $clientConfig = isset($config['elastica']['clients']) ? $config['elastica']['clients'] : [];
     $entityConfig = isset($config['elastica']['entities']) ? $config['elastica']['entities'] : ['paths' => []];
     $indicesConfig = isset($config['elastica']['indices']) ? $config['elastica']['indices'] : [];
     $serializationGroups = isset($config['elastica']['serialization']['groups']) ? $config['elastica']['serialization']['groups'] : [];
     $searchConfig = new Configuration();
     $md = $searchConfig->newDefaultAnnotationDriver($entityConfig['paths']);
     $searchConfig->setMetadataDriverImpl($md);
     $searchConfig->setMetadataCacheImpl(new ArrayCache());
     $serializationContext = SerializationContext::create();
     $serializationContext->enableMaxDepthChecks()->setGroups($serializationGroups);
     $searchConfig->setEntitySerializer(new JMSSerializer($serializationContext));
     $eventManager = new EventManager();
     $searchManager = new SearchManager($searchConfig, new ElasticSearchClient(new ElasticaClient(['connections' => $clientConfig])), $eventManager);
     try {
         $client = $searchManager->getClient();
         $metadatas = $searchManager->getMetadataFactory()->getAllMetadata();
         // Create indexes and types
         foreach ($metadatas as $metadata) {
             $config = isset($indicesConfig[$metadata->index]['settings']) ? $indicesConfig[$metadata->index]['settings'] : [];
             if (!$client->getIndex($metadata->index)->exists()) {
                 $client->createIndex($metadata->index, $config);
             }
             $client->createType($metadata);
         }
     } catch (\Exception $e) {
         $this->getFlashMessenger()->addErrorMessage($e->getMessage());
         /* @var $logger \Zend\Log\Logger */
         $logger = $serviceLocator->get('logger');
         $logger->debug($e->getMessage());
     }
     return $searchManager;
 }
예제 #10
0
 /**
  * Delete all indices
  */
 public function deleteAllIndices()
 {
     /** @var ClassMetadata[] $metadatas */
     $metadatas = $this->sm->getMetadataFactory()->getAllMetadata();
     foreach ($metadatas as $metadata) {
         try {
             $this->client->deleteIndex($metadata->getIndexForRead());
         } catch (ResponseException $e) {
             if (strpos($e->getResponse()->getError(), 'IndexMissingException') === false) {
                 // The original error from ES is not "IndexMissingException". We shouldn't swallow it.
                 throw $e;
             }
             // The index has been deleted already, skip it.
         }
     }
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $metaFactory = $this->searchManager->getClassMetadataFactory();
     /** @var \Doctrine\Search\Mapping\ClassMetadata[] $classes */
     $allClassesForIndex = $metaFactory->getAllMetadata();
     if ($onlyEntity = $input->getOption('entity')) {
         $classes = [$metaFactory->getMetadataFor($onlyEntity)];
     } else {
         $classes = $metaFactory->getAllMetadata();
     }
     /** @var ProgressBar $progress */
     $progress = NULL;
     $this->entityPiper->onIndexStart[] = function ($ep, Nette\Utils\Paginator $paginator, EntityRiver $river, ORMMetadata $class) use($output, &$progress) {
         $output->writeln(sprintf('Indexing <info>%s</info> using <info>%s</info>', $class->getName(), get_class($river)));
         if ($paginator->getItemCount() <= 0) {
             $output->writeln(" 0/0 River didn't return any results");
             return;
         }
         $progress = new ProgressBar($output, $paginator->getItemCount());
         $progress->setFormat($progress::getFormatDefinition('debug'));
         $progress->start();
     };
     $this->entityPiper->onIndexStats[] = function ($ep, ORMMetadata $meta, $timeToIndex, $timeToRead) use($input, $output) {
         if (!$input->getOption('stats')) {
             return;
         }
         $format = function ($time) {
             if ($time < 10) {
                 return number_format($time * 1000, 6, '.', '') . ' ms';
             } else {
                 return number_format($time, 2, '.', '') . ' s';
             }
         };
         $output->writeln(sprintf(" ... Loading data took %s, indexing took %s", $format($timeToRead), $format($timeToIndex)));
     };
     $this->entityPiper->onItemsIndexed[] = function ($ep, $entities) use($output, &$progress) {
         $progress->advance(count($entities));
     };
     $this->entityPiper->onChildSkipped[] = function ($ep, ClassMetadata $meta, ClassMetadata $parent) use($output, &$progress) {
         $output->writeln(sprintf('<info>%s</info> is a subclass of <info>%s</info> (being piped into <info>%s</info> type), ignoring.', $meta->className, $parent->className, $parent->type->name));
         $progress = NULL;
     };
     $aliases = array();
     $indexAliases = $input->getArgument('index-aliases');
     foreach ($indexAliases as $tmp) {
         list($alias, $original) = explode('=', $tmp, 2);
         $aliases[$original] = $alias;
     }
     foreach ($allClassesForIndex as $class) {
         //subclass bug
         if (isset($aliases[$class->getIndexName()])) {
             $class->index->name = $aliases[$class->getIndexName()];
         }
     }
     foreach ($classes as $class) {
         $output->writeln('');
         if ($old = array_search($class->getIndexName(), $aliases, TRUE)) {
             $output->writeln(sprintf('Redirecting data from <info>%s</info> to <info>%s</info>', $old, $class->getIndexName()));
         }
         unset($e);
         try {
             $this->entityPiper->indexEntities($class);
         } catch (\Exception $e) {
         }
         if (isset($e)) {
             // fix the metadata
             if ($old = array_search($class->getIndexName(), $aliases, TRUE)) {
                 $class->index->name = $old;
             }
             throw $e;
         }
         if ($progress !== NULL) {
             $progress->finish();
         }
         $output->writeln('');
     }
     foreach ($allClassesForIndex as $class) {
         //subclass bug
         // fix the metadata
         if ($old = array_search($class->getIndexName(), $aliases, TRUE)) {
             $class->index->name = $old;
         }
     }
 }
예제 #12
0
 /**
  * Execute a direct delete by query on the associated index and type
  *
  * @param object $query
  */
 public function delete($query)
 {
     $this->_sm->getClient()->removeAll($this->_class, $query);
 }
예제 #13
0
 public function testGetClassMetadataFactory()
 {
     $mdf = $this->sm->getClassMetadataFactory();
     $this->assertInstanceOf('Doctrine\\Search\\Mapping\\ClassMetadataFactory', $mdf);
 }
예제 #14
0
 /**
  * {@inheritDoc}
  */
 protected function initialize()
 {
     $this->driver = $this->config->getMetadataDriverImpl();
     $this->evm = $this->sm->getEventManager();
     $this->initialized = true;
 }
예제 #15
0
 protected function doRemoveEntities($entities)
 {
     $this->searchManager->remove($entities);
 }