Author: Rodolfo Adhenawer Campagnoli Moraes (adhenawer@gmail.com)
Author: Wong Wing Lun (luiges90@gmail.com)
Author: Tristan Maindron (tmaindron@gmail.com)
Inheritance: extends AbstractQuery
Ejemplo n.º 1
2
 public function findWithTenant($searchText, $tenantId, $sortDirection = 'desc')
 {
     $boolFilter = new Filter\Bool();
     $boolFilter->addMust(new Filter\Term(['tenant.id' => $tenantId]));
     $boolQuery = new Query\Bool();
     if ($searchText !== null) {
         $fieldQuery = new Query\MultiMatch();
         $fieldQuery->setQuery("*" . $searchText . "*");
         $fieldQuery->setFields(['name', 'description']);
         $boolQuery->addMust($fieldQuery);
     }
     $filtered = new Query\Filtered($boolQuery, $boolFilter);
     $query = Query::create($filtered);
     $query->addSort(['created_at' => $sortDirection]);
     return $this->findPaginated($query);
 }
Ejemplo n.º 2
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);
 }
Ejemplo n.º 3
0
 public function testQuery()
 {
     $client = $this->_getClient();
     $index = new Index($client, 'test');
     $index->create(array(), true);
     $type = new Type($index, 'multi_match');
     $doc = new Document(1, array('id' => 1, 'name' => 'Rodolfo', 'last_name' => 'Moraes'));
     $type->addDocument($doc);
     // Refresh index
     $index->refresh();
     $multiMatch = new MultiMatch();
     $query = new Query();
     $multiMatch->setQuery('Rodolfo');
     $multiMatch->setFields(array('name', 'last_name'));
     $query->setQuery($multiMatch);
     $resultSet = $index->search($query);
     $this->assertEquals(1, $resultSet->count());
     $multiMatch->setQuery('Moraes');
     $multiMatch->setFields(array('name', 'last_name'));
     $query->setQuery($multiMatch);
     $resultSet = $index->search($query);
     $this->assertEquals(1, $resultSet->count());
 }
 /**
  * @param string[] $fields
  * @param string[] $nearMatchFields
  * @param string $queryString
  * @param string $nearMatchQuery
  * @return \Elastica\Query\Simple|\Elastica\Query\Bool
  */
 private function buildSearchTextQuery(array $fields, array $nearMatchFields, $queryString, $nearMatchQuery)
 {
     $queryForMostFields = $this->buildSearchTextQueryForFields($fields, $queryString, $this->config->getElement('CirrusSearchPhraseSlop', 'default'), false);
     if ($nearMatchQuery) {
         // Build one query for the full text fields and one for the near match fields so that
         // the near match can run unescaped.
         $bool = new \Elastica\Query\Bool();
         $bool->setMinimumNumberShouldMatch(1);
         $bool->addShould($queryForMostFields);
         $nearMatch = new \Elastica\Query\MultiMatch();
         $nearMatch->setFields($nearMatchFields);
         $nearMatch->setQuery($nearMatchQuery);
         $bool->addShould($nearMatch);
         return $bool;
     }
     return $queryForMostFields;
 }
Ejemplo n.º 5
0
 /**
  * Find all documents where the value is matched in the fields. The type option
  * allows you to specify the type of match, can be best_fields, most_fields,
  * cross_fields, phrase, phrase_prefix.
  *
  * best_fields finds documents which match any field, but uses the _score
  * from the best field.
  *
  * most_fields finds documents which match any field and combines the _score
  * from each field.
  *
  * cross_fields treats fields with the same analyzer as though they were
  * one big field. Looks for each word in any field.
  *
  * phrase runs a match_phrase query on each field and combines the _score
  * from each field.
  *
  * phrase_prefix runs a match_phrase_prefix query on each field and combines
  * the _score from each field.
  *
  * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
  *
  * @param array $fields The fields to search in
  * @param string $query The string to search for
  * @param string $type The match type
  * @param bool $fuzzy Set whether the match should be fuzzy
  * @param float $tieBreaker Can be between 0.0 and 1.0
  * @param string $operator Can be 'and' or 'or'
  * @return Query
  */
 public function multiMatch(array $fields, $query, $type = 'phrase', $fuzzy = false, $tieBreaker = 0.0, $operator = 'and')
 {
     $match = new MultiMatch();
     $match->setFields($fields);
     $match->setQuery($query);
     $match->setType($type);
     if ($fuzzy) {
         $match->setFuzziness('AUTO');
     }
     if ($type == 'best_fields') {
         $match->setTieBreaker($tieBreaker);
     }
     if ($type == 'cross_fields') {
         $match->setOperator($operator);
     }
     $query = $this->newQuery($match);
     $this->query[] = $query;
     return $query;
 }
Ejemplo n.º 6
0
 /**
  * @group functional
  */
 public function testBaseMultiMatch()
 {
     $multiMatch = new MultiMatch();
     $multiMatch->setQuery('Rodolfo');
     $multiMatch->setFields(array('name', 'last_name'));
     $resultSet = $this->_getResults($multiMatch);
     $this->assertEquals(1, $resultSet->count());
     $multiMatch = new MultiMatch();
     $multiMatch->setQuery('Moraes');
     $multiMatch->setFields(array('name', 'last_name'));
     $resultSet = $this->_getResults($multiMatch);
     $this->assertEquals(1, $resultSet->count());
 }
Ejemplo n.º 7
0
 public function search()
 {
     //$finder = $this->container->get('fos_elastica.finder.search.articles');
     $bool = new Query\Bool();
     $multiMatch = new Query\MultiMatch();
     $multiMatch->setFields(['subjects', 'title', 'keywords', 'subtitle', 'citations.raw', 'journal.title', 'journal.subtitle']);
     $multiMatch->setType('phrase_prefix');
     $multiMatch->setQuery($this->getParam('term'));
     $bool->addMust($multiMatch);
     if ($this->filter) {
         foreach ($this->filter as $key => $filter) {
             $filterObj = new Query\Match();
             $this->applyFilter($filterObj, $key, $filter);
             $bool->addMust($filterObj);
         }
     }
     $missing = new Filter\Missing("issue");
     $not = new Filter\BoolNot($missing);
     $notQ = new Query\Filtered();
     $notQ->setFilter($not);
     $bool->addMust($notQ);
     $query = new Query();
     $query->setQuery($bool);
     $query->setFrom($this->getPage() * $this->getLimit());
     $query->setSize($this->getLimit());
     $aggregation = new Terms('journals');
     $aggregation->setField('journal.id');
     $aggregation->setOrder('_count', 'desc');
     $qb = $this->em->createQueryBuilder();
     $qb->select('count(r.id)')->from('OjsJournalBundle:Journal', 'r')->where($qb->expr()->eq('r.status', 3));
     $aggregation->setSize($qb->getQuery()->getSingleScalarResult());
     $query->addAggregation($aggregation);
     $aggregation = new Terms('authors');
     $aggregation->setField('articleAuthors.author.id');
     $aggregation->setOrder('_count', 'desc');
     $qb = $this->em->createQueryBuilder();
     $qb->select('count(r.id)')->from('OjsJournalBundle:Author', 'r');
     $aggregation->setSize($qb->getQuery()->getSingleScalarResult());
     $query->addAggregation($aggregation);
     $elasticaAdapter = new ElasticaAdapter($this->index, $query);
     $pagerFanta = new Pagerfanta($elasticaAdapter);
     $pagerFanta->setMaxPerPage($this->getLimit());
     $pagerFanta->setCurrentPage($this->getPage());
     /** @var ResultSet $search */
     $search = $pagerFanta->getCurrentPageResults();
     $result = $search->getResults();
     //$search->getResults();
     $this->pager = $pagerFanta;
     $transformer = new ElasticaToModelTransformer($this->registry, 'OjsJournalBundle:Article');
     $transformer->setPropertyAccessor($this->propertyAccessor);
     $this->result = $transformer->transform($result);
     $this->setCount($pagerFanta->getNbResults());
     $this->addAggregation('journal', $this->transform($search->getAggregation('journals')['buckets'], 'OjsJournalBundle:Journal'));
     $this->addAggregation('author', $this->transform($search->getAggregation('authors')['buckets'], 'OjsJournalBundle:Author'));
     return $this;
 }
Ejemplo n.º 8
0
 /**
  * @param Request $request
  * @return JsonResponse
  */
 public function autoCompleteAction(Request $request)
 {
     $q = filter_var($request->get('q'), FILTER_SANITIZE_STRING);
     $search = $this->get('fos_elastica.index.search.journal');
     $notCollectJournals = [];
     if ($request->query->has('notCollectJournals')) {
         $notCollectJournalsParam = $request->query->get('notCollectJournals');
         if (!empty($notCollectJournalsParam) && is_array($notCollectJournalsParam)) {
             $notCollectJournals = $notCollectJournalsParam;
         }
     }
     $searchQuery = new Query('_all');
     $boolQuery = new Query\BoolQuery();
     $fieldQuery = new Query\MultiMatch();
     $fieldQuery->setFields(['title']);
     $fieldQuery->setQuery(strtoupper($q));
     $fieldQuery->setFuzziness(0.7);
     $boolQuery->addMust($fieldQuery);
     $searchQuery->setQuery($boolQuery);
     $searchQuery->setSize(10);
     $results = $search->search($searchQuery);
     $data = [];
     foreach ($results as $result) {
         if (!in_array($result->getId(), $notCollectJournals)) {
             $data[] = ['id' => $result->getId(), 'text' => $result->getData()['title']];
         }
     }
     return new JsonResponse($data);
 }