/** * 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()); }
/** * @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; }