/**
  * Reset sphinx client and apply the options
  *
  * Only apply filters and group by
  *
  * @param  SearchEngineOptions $options
  * @return SphinxSearch
  */
 protected function applyOptions(SearchEngineOptions $options)
 {
     $this->resetSphinx();
     $filters = [];
     foreach ($options->getCollections() as $collection) {
         $filters[] = sprintf("%u", crc32($collection->get_databox()->get_sbas_id() . '_' . $collection->get_coll_id()));
     }
     $this->sphinx->SetFilter('crc_sbas_coll', $filters);
     $this->sphinx->SetFilter('deleted', [0]);
     $this->sphinx->SetFilter('parent_record_id', [$options->getSearchType()]);
     if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
         foreach (array_unique(array_map(function (\databox_field $field) {
             return $field->get_name();
         }, $options->getDateFields())) as $field) {
             $min = $options->getMinDate() ? $options->getMinDate()->format('U') : 0;
             $max = $options->getMaxDate() ? $options->getMaxDate()->format('U') : pow(2, 32);
             $this->sphinx->SetFilterRange(ConfigurationPanel::DATE_FIELD_PREFIX . $field, $min, $max);
         }
     }
     if ($options->getFields()) {
         $filters = [];
         foreach ($options->getFields() as $field) {
             $filters[] = sprintf("%u", crc32($field->get_databox()->get_sbas_id() . '_' . $field->get_id()));
         }
         $this->sphinx->SetFilter('crc_struct_id', $filters);
     }
     if ($options->getBusinessFieldsOn()) {
         $crc_coll_business = [];
         foreach ($options->getBusinessFieldsOn() as $collection) {
             $crc_coll_business[] = sprintf("%u", crc32($collection->get_coll_id() . '_1'));
             $crc_coll_business[] = sprintf("%u", crc32($collection->get_coll_id() . '_0'));
         }
         $non_business = [];
         foreach ($options->getCollections() as $collection) {
             foreach ($options->getBusinessFieldsOn() as $BFcollection) {
                 if ($collection->get_base_id() == $BFcollection->get_base_id()) {
                     continue 2;
                 }
             }
             $non_business[] = $collection;
         }
         foreach ($non_business as $collection) {
             $crc_coll_business[] = sprintf("%u", crc32($collection->get_coll_id() . '_0'));
         }
         $this->sphinx->SetFilter('crc_coll_business', $crc_coll_business);
     } elseif ($options->getFields()) {
         $this->sphinx->SetFilter('business', [0]);
     }
     /**
      * @todo : enhance : check status in a better way
      */
     $status_opts = $options->getStatus();
     foreach ($options->getDataboxes() as $databox) {
         foreach ($databox->get_statusbits() as $n => $status) {
             if (!array_key_exists($n, $status_opts)) {
                 continue;
             }
             if (!array_key_exists($databox->get_sbas_id(), $status_opts[$n])) {
                 continue;
             }
             $crc = sprintf("%u", crc32($databox->get_sbas_id() . '_' . $n));
             $this->sphinx->SetFilter('status', [$crc], $status_opts[$n][$databox->get_sbas_id()] == '0');
         }
     }
     if ($options->getRecordType()) {
         $this->sphinx->SetFilter('crc_type', [sprintf("%u", crc32($options->getRecordType()))]);
     }
     $order = '';
     switch ($options->getSortOrder()) {
         case SearchEngineOptions::SORT_MODE_ASC:
             $order = 'ASC';
             break;
         case SearchEngineOptions::SORT_MODE_DESC:
         default:
             $order = 'DESC';
             break;
     }
     switch ($options->getSortBy()) {
         case SearchEngineOptions::SORT_RANDOM:
             $sort = '@random';
             break;
         case SearchEngineOptions::SORT_RELEVANCE:
         default:
             $sort = '@relevance ' . $order . ', created_on ' . $order;
             break;
         case SearchEngineOptions::SORT_CREATED_ON:
             $sort = 'created_on ' . $order;
             break;
     }
     $this->sphinx->SetGroupBy('crc_sbas_record', SPH_GROUPBY_ATTR, $sort);
     return $this;
 }
Exemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function query($query, $offset, $perPage, SearchEngineOptions $options = null)
 {
     if (null === $options) {
         $options = new SearchEngineOptions();
     }
     $this->initialize();
     $this->checkSession();
     $this->clearAllCache(new \DateTime('-1 hour'));
     assert(is_int($offset));
     assert($offset >= 0);
     assert(is_int($perPage));
     if (trim($query) === '') {
         $query = "all";
     }
     if ($options->getRecordType()) {
         $query .= ' AND recordtype=' . $options->getRecordType();
     }
     $sql = 'SELECT query, query_time, duration, total FROM cache WHERE session_id = :ses_id';
     $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
     $stmt->execute([':ses_id' => $this->app['session']->get('phrasea_session_id')]);
     $row = $stmt->fetch(\PDO::FETCH_ASSOC);
     $stmt->closeCursor();
     $date_obj = new \DateTime('-10 min');
     $date_quest = new \DateTime($row['query_time']);
     if ($query != $row['query']) {
         $this->resetCacheNextQuery = true;
     }
     if ($date_obj > $date_quest) {
         $this->resetCacheNextQuery = true;
     }
     if ($this->resetCacheNextQuery === true) {
         phrasea_clear_cache($this->app['session']->get('phrasea_session_id'));
         $this->addQuery($query, $options);
         $this->executeQuery($query, $options);
         $sql = 'SELECT query, query_time, duration, total FROM cache WHERE session_id = :ses_id';
         $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
         $stmt->execute([':ses_id' => $this->app['session']->get('phrasea_session_id')]);
         $row = $stmt->fetch(\PDO::FETCH_ASSOC);
         $stmt->closeCursor();
     } else {
         /**
          * @todo clean this in DB
          */
         $this->total_available = $this->total_results = $this->app['session']->get('phrasea_engine_n_results');
     }
     $res = phrasea_fetch_results($this->app['session']->get('phrasea_session_id'), $offset + 1, $perPage, false);
     $rs = [];
     $error = $this->app->trans('Unable to execute query');
     if (isset($res['results']) && is_array($res['results'])) {
         $rs = $res['results'];
         $error = '';
     }
     $resultNumber = $offset;
     $records = new ArrayCollection();
     foreach ($rs as $data) {
         try {
             $records->add(new \record_adapter($this->app, \phrasea::sbasFromBas($this->app, $data['base_id']), $data['record_id'], $resultNumber));
         } catch (\Exception $e) {
         }
         $resultNumber++;
     }
     $propositions = $this->getPropositions();
     $suggestions = $this->getSuggestions($query);
     return new SearchEngineResult($records, $query, $row['duration'], $offset, $row['total'], $row['total'], $error, '', $suggestions, $propositions, '');
 }
Exemplo n.º 3
0
 private function createFilters(SearchEngineOptions $options)
 {
     $filters = [];
     $status_opts = $options->getStatus();
     foreach ($options->getDataboxes() as $databox) {
         foreach ($databox->get_statusbits() as $n => $status) {
             if (!array_key_exists($n, $status_opts)) {
                 continue;
             }
             if (!array_key_exists($databox->get_sbas_id(), $status_opts[$n])) {
                 continue;
             }
             $filters[] = ['term' => ['status.status-' . $n => $status_opts[$n][$databox->get_sbas_id()]]];
         }
     }
     $filters[] = ['terms' => ['base_id' => array_map(function (\collection $coll) {
         return $coll->get_base_id();
     }, $options->getCollections())]];
     $filters[] = ['term' => ['type' => $options->getSearchType() === SearchEngineOptions::RECORD_RECORD ? 'record' : 'story']];
     if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
         $range = [];
         if ($options->getMaxDate()) {
             $range['lte'] = $options->getMaxDate()->format(DATE_ATOM);
         }
         if ($options->getMinDate()) {
             $range['gte'] = $options->getMinDate()->format(DATE_ATOM);
         }
         foreach ($options->getDateFields() as $dateField) {
             $filters[] = ['range' => ['caption.' . $dateField->get_name() => $range]];
         }
     }
     if ($options->getRecordType()) {
         $filters[] = ['term' => ['phrasea_type' => $options->getRecordType()]];
     }
     return $filters;
 }
Exemplo n.º 4
0
 private function createQueryFilters(SearchEngineOptions $options)
 {
     $filters = [];
     $filters[]['term']['record_type'] = $options->getSearchType() === SearchEngineOptions::RECORD_RECORD ? SearchEngineInterface::GEM_TYPE_RECORD : SearchEngineInterface::GEM_TYPE_STORY;
     if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
         $range = [];
         if ($options->getMaxDate()) {
             $range['lte'] = $options->getMaxDate()->format(Mapping::DATE_FORMAT_CAPTION_PHP);
         }
         if ($options->getMinDate()) {
             $range['gte'] = $options->getMinDate()->format(Mapping::DATE_FORMAT_CAPTION_PHP);
         }
         foreach ($options->getDateFields() as $dateField) {
             $filters[]['range']['caption.' . $dateField->get_name()] = $range;
         }
     }
     if ($type = $options->getRecordType()) {
         $filters[]['term']['type'] = $type;
     }
     $collections = $options->getCollections();
     if (count($collections) > 0) {
         $filters[]['terms']['base_id'] = array_keys($collections);
     }
     if (count($options->getStatus()) > 0) {
         $status_filters = [];
         $flagNamesMap = $this->getFlagsKey($this->app['phraseanet.appbox']);
         foreach ($options->getStatus() as $databoxId => $status) {
             $status_filter = $databox_status = [];
             $status_filter[] = ['term' => ['databox_id' => $databoxId]];
             foreach ($status as $n => $v) {
                 if (!isset($flagNamesMap[$databoxId][$n])) {
                     continue;
                 }
                 $label = $flagNamesMap[$databoxId][$n];
                 $databox_status[] = ['term' => [sprintf('flags.%s', $label) => (bool) $v]];
             }
             $status_filter[] = $databox_status;
             $status_filters[] = ['bool' => ['must' => $status_filter]];
         }
         $filters[]['bool']['should'] = $status_filters;
     }
     return $filters;
 }