예제 #1
1
 /**
  * search page index controller
  *
  * @param Request $request
  * @param int $page
  * @return \Symfony\Component\HttpFoundation\Response
  */
 public function indexAction(Request $request, $page = 1)
 {
     /**
      * @var \Ojs\SearchBundle\Manager\SearchManager $searchManager
      */
     $searchManager = $this->get('ojs_search_manager');
     $getRoles = $request->query->get('role_filters');
     $getSubjects = $request->query->get('subject_filters');
     $getJournals = $request->query->get('journal_filters');
     $roleFilters = !empty($getRoles) ? explode(',', $getRoles) : [];
     $subjectFilters = !empty($getSubjects) ? explode(',', $getSubjects) : [];
     $journalFilters = !empty($getJournals) ? explode(',', $getJournals) : [];
     $queryType = $request->query->has('type') ? $request->get('type') : 'basic';
     $query = filter_var($request->get('q'), FILTER_SANITIZE_STRING);
     $section = filter_var($request->get('section'), FILTER_SANITIZE_STRING);
     $searcher = $this->get('fos_elastica.index.search');
     $searchQuery = new Query('_all');
     $boolQuery = new Query\Bool();
     $match = new Query\Match();
     $match->setField('status', 3);
     $boolQuery->addShould($match);
     $match = new Query\Match();
     $match->setField('published', true);
     $boolQuery->addShould($match);
     //set query according to query type
     if ($queryType == 'basic') {
         $fieldQuery = new Query\MultiMatch();
         $fieldQuery->setFields(['_all']);
         $fieldQuery->setQuery($query);
         $boolQuery->addMust($fieldQuery);
     } elseif ($queryType == 'advanced') {
         $parseQuery = $searchManager->parseSearchQuery($query);
         foreach ($parseQuery as $searchTerm) {
             $condition = $searchTerm['condition'];
             $advancedFieldQuery = new Query\MultiMatch();
             $advancedFieldQuery->setFields([$searchTerm['searchField']]);
             $advancedFieldQuery->setQuery($searchTerm['searchText']);
             if ($condition == 'AND') {
                 $boolQuery->addMust($advancedFieldQuery);
             } elseif ($condition == 'OR') {
                 $boolQuery->addShould($advancedFieldQuery);
             } elseif ($condition == 'NOT') {
                 $boolQuery->addMustNot($advancedFieldQuery);
             }
         }
     } elseif ($queryType == 'tag') {
         $matchQuery = new Query\Match();
         $matchQuery->setField('tags', $query);
         $boolQuery->addMust($matchQuery);
     }
     //set aggregations if requested
     if (!empty($roleFilters) || !empty($subjectFilters) || !empty($journalFilters)) {
         foreach ($roleFilters as $role) {
             $match = new Query\Match();
             $match->setField('user.userJournalRoles.role.name', $role);
             $boolQuery->addMust($match);
         }
         foreach ($subjectFilters as $subject) {
             $match = new Query\Match();
             $match->setField('subjects', $subject);
             $boolQuery->addMust($match);
         }
         foreach ($journalFilters as $journal) {
             $match = new Query\Match();
             $match->setField('user.userJournalRoles.journal.title', $journal);
             $boolQuery->addMust($match);
         }
     }
     //set our boolean query
     $searchQuery->setQuery($boolQuery);
     //get all result
     $searchQuery->setSize(1000);
     //get role aggregation
     $roleAgg = new Aggregation\Terms('roles');
     $roleAgg->setField('userJournalRoles.role.name');
     $roleAgg->setOrder('_term', 'asc');
     $roleAgg->setSize(0);
     $searchQuery->addAggregation($roleAgg);
     //get subject aggregation
     $subjectAgg = new Aggregation\Terms('subjects');
     $subjectAgg->setField('subjects');
     $subjectAgg->setOrder('_term', 'asc');
     $subjectAgg->setSize(0);
     $searchQuery->addAggregation($subjectAgg);
     //get journal aggregation
     $journalAgg = new Aggregation\Terms('journals');
     $journalAgg->setField('journal.raw');
     $journalAgg->setOrder('_term', 'asc');
     $journalAgg->setSize(0);
     $searchQuery->addAggregation($journalAgg);
     /**
      * @var ResultSet $resultData
      */
     $resultData = $searcher->search($searchQuery);
     $roles = $resultData->getAggregation('roles')['buckets'];
     $subjects = $resultData->getAggregation('subjects')['buckets'];
     $journals = $resultData->getAggregation('journals')['buckets'];
     if ($resultData->count() > 0) {
         /**
          * manipulate result data for easily use on template
          */
         $results = $searchManager->buildResultsObject($resultData, $section);
         /**
          * if search section is not defined or empty redirect to first result section
          */
         if (empty($section)) {
             $section = array_keys($results)[0];
             $redirectParams = array_merge($request->query->all(), ['section' => $section]);
             return $this->redirectToRoute('ojs_search_index', $redirectParams);
         } else {
             /**
              * if section result is empty redirect to first that have result section
              */
             if (!isset($results[$section])) {
                 foreach ($results as $resultKey => $result) {
                     if ($result['total_item'] > 0) {
                         $redirectParams = array_merge($request->query->all(), ['section' => $resultKey]);
                         return $this->redirectToRoute('ojs_search_index', $redirectParams);
                     }
                 }
             }
         }
         $adapter = new ArrayAdapter($results[$section]['data']);
         $pagerfanta = new Pagerfanta($adapter);
         $pagerfanta->setMaxPerPage(10);
         $pagerfanta->setCurrentPage($page);
         $results[$section]['data'] = $pagerfanta->getCurrentPageResults();
         /**
          * add search query to query history
          * history data stores on session
          */
         $this->addQueryToHistory($request, $query, $queryType, $resultData->count());
         $data = ['results' => $results, 'query' => $query, 'queryType' => $queryType, 'section' => $section, 'total_count' => $searchManager->getTotalHit(), 'roles' => $roles, 'subjects' => $subjects, 'journals' => $journals, 'role_filters' => $roleFilters, 'subject_filters' => $subjectFilters, 'journal_filters' => $journalFilters, 'pagerfanta' => $pagerfanta];
     } else {
         $data = ['query' => $query, 'queryType' => $queryType, 'total_count' => $searchManager->getTotalHit(), 'journals' => []];
     }
     return $this->render('OjsSiteBundle:Search:index.html.twig', $data);
 }
 public function testToArray()
 {
     $query = new Bool();
     $idsQuery1 = new Ids();
     $idsQuery1->setIds(1);
     $idsQuery2 = new Ids();
     $idsQuery2->setIds(2);
     $idsQuery3 = new Ids();
     $idsQuery3->setIds(3);
     $boost = 1.2;
     $minMatch = 2;
     $query->setBoost($boost);
     $query->setMinimumNumberShouldMatch($minMatch);
     $query->addMust($idsQuery1);
     $query->addMustNot($idsQuery2);
     $query->addShould($idsQuery3->toArray());
     $expectedArray = array('bool' => array('must' => array($idsQuery1->toArray()), 'should' => array($idsQuery3->toArray()), 'minimum_number_should_match' => $minMatch, 'must_not' => array($idsQuery2->toArray()), 'boost' => $boost));
     $this->assertEquals($expectedArray, $query->toArray());
 }
예제 #3
0
 /**
  * @param $searchClosed
  * @return \Elastica\ResultSet
  * @throws Exception
  */
 public function doSearch($searchClosed)
 {
     $this->connection = new ElasticSearchConnection();
     $this->connection->init();
     $this->whereClause = new Query\QueryString();
     $this->whereClause->setQuery($this->searchTerms);
     $this->utility = new Util();
     if (isset($_GET['page'])) {
         $this->currentPage = intval($_GET['page']);
     }
     $this->fieldMapping = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'WMDB.Forger.SearchTermMapping');
     $elasticaQuery = new Query();
     if ($searchClosed === 'true') {
         $elasticaQuery->setQuery($this->whereClause);
     } else {
         $boolSearch = new Query\Bool();
         $boolSearch->addMust($this->whereClause);
         $boolSearch->addMustNot(['term' => ['status.name' => 'Closed']]);
         $boolSearch->addMustNot(['term' => ['status.name' => 'Rejected']]);
         $boolSearch->addMustNot(['term' => ['status.name' => 'Resolved']]);
         $elasticaQuery->setQuery($boolSearch);
     }
     $elasticaQuery->setSize($this->perPage);
     $elasticaQuery->setFrom($this->currentPage * $this->perPage - $this->perPage);
     $usedFilters = $this->addFilters();
     if ($usedFilters !== false) {
         $elasticaQuery->setPostFilter($usedFilters);
     }
     $this->addAggregations($elasticaQuery);
     $elasticaResultSet = $this->connection->getIndex()->search($elasticaQuery);
     $results = $elasticaResultSet->getResults();
     $maxScore = $elasticaResultSet->getMaxScore();
     $aggs = $elasticaResultSet->getAggregations();
     $this->totalHits = $elasticaResultSet->getTotalHits();
     $out = array('pagesToLinkTo' => $this->getPages(), 'currentPage' => $this->currentPage, 'prev' => $this->currentPage - 1, 'next' => $this->currentPage < ceil($this->totalHits / $this->perPage) ? $this->currentPage + 1 : 0, 'totalResults' => $this->totalHits, 'startingAtItem' => $this->currentPage * $this->perPage - ($this->perPage - 1), 'endingAtItem' => $this->currentPage * $this->perPage, 'results' => $results, 'maxScore' => $maxScore, 'aggs' => $aggs);
     if (intval($this->totalHits) <= intval($out['endingAtItem'])) {
         $out['endingAtItem'] = intval($this->totalHits);
     }
     return $out;
 }