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);
 }
示例#2
1
 public function publisherAction(Request $request, $page = 1)
 {
     $getTypes = $request->query->get('type_filters');
     $typeFilters = !empty($getTypes) ? explode(',', $getTypes) : [];
     $publisherSearcher = $this->get('fos_elastica.index.search.publisher');
     $boolQuery = new Query\Bool();
     if (!empty($typeFilters)) {
         foreach ($typeFilters as $type) {
             $match = new Query\Match();
             $match->setField('publisherType', $type);
             $boolQuery->addMust($match);
         }
     }
     $publisherQuery = new Query($boolQuery);
     $typeAgg = new Aggregation\Terms('types');
     $typeAgg->setField('publisherType');
     $typeAgg->setOrder('_term', 'asc');
     $typeAgg->setSize(0);
     $publisherQuery->addAggregation($typeAgg);
     $adapter = new ElasticaAdapter($publisherSearcher, $publisherQuery);
     $pagerfanta = new Pagerfanta($adapter);
     $pagerfanta->setMaxPerPage(20);
     $pagerfanta->setCurrentPage($page);
     $publishers = $pagerfanta->getCurrentPageResults();
     $types = $adapter->getResultSet()->getAggregation('types')['buckets'];
     $data = ['types' => $types, 'page' => 'ojs_site_explore_publisher', 'publishers' => $publishers, 'pagerfanta' => $pagerfanta, 'type_filters' => $typeFilters];
     return $this->render('OjsSiteBundle:Explore:publisher.html.twig', $data);
 }
示例#3
1
 public function indexAction(Request $request, $page = 1)
 {
     $getTypes = $request->query->get('type_filters');
     $getSubjects = $request->query->get('subject_filters');
     $getPublishers = $request->query->get('publisher_filters');
     $typeFilters = !empty($getTypes) ? explode(',', $getTypes) : [];
     $subjectFilters = !empty($getSubjects) ? explode(',', $getSubjects) : [];
     $publisherFilters = !empty($getPublishers) ? explode(',', $getPublishers) : [];
     $journalSearcher = $this->get('fos_elastica.index.search.journal');
     $boolQuery = new Query\Bool();
     $match = new Query\Match();
     $match->setField('status', 1);
     $boolQuery->addMust($match);
     $match = new Query\Match();
     $match->setField('published', true);
     $boolQuery->addMust($match);
     if (!empty($typeFilters) || !empty($subjectFilters) || !empty($publisherFilters)) {
         foreach ($typeFilters as $type) {
             $match = new Query\Match();
             $match->setField('publisher.publisher_type.name', $type);
             $boolQuery->addMust($match);
         }
         foreach ($subjectFilters as $subject) {
             $match = new Query\Match();
             $match->setField('subjects.subject', $subject);
             $boolQuery->addMust($match);
         }
         foreach ($publisherFilters as $publisher) {
             $match = new Query\Match();
             $match->setField('publisher.name', $publisher);
             $boolQuery->addMust($match);
         }
     }
     $journalQuery = new Query($boolQuery);
     $typeAgg = new Aggregation\Terms('types');
     $typeAgg->setField('publisher.publisher_type.name');
     $typeAgg->setOrder('_term', 'asc');
     $typeAgg->setSize(0);
     $journalQuery->addAggregation($typeAgg);
     $subjectAgg = new Aggregation\Terms('subjects');
     $subjectAgg->setField('subjects.subject');
     $subjectAgg->setOrder('_term', 'asc');
     $subjectAgg->setSize(0);
     $journalQuery->addAggregation($subjectAgg);
     $publisherAgg = new Aggregation\Terms('publishers');
     $publisherAgg->setField('publisher.name');
     $publisherAgg->setOrder('_term', 'asc');
     $publisherAgg->setSize(0);
     $journalQuery->addAggregation($publisherAgg);
     $adapter = new ElasticaAdapter($journalSearcher, $journalQuery);
     $pagerfanta = new Pagerfanta($adapter);
     $pagerfanta->setMaxPerPage(21);
     $pagerfanta->setCurrentPage($page);
     $journals = $pagerfanta->getCurrentPageResults();
     $types = $adapter->getResultSet()->getAggregation('types')['buckets'];
     $subjects = $adapter->getResultSet()->getAggregation('subjects')['buckets'];
     $publishers = $adapter->getResultSet()->getAggregation('publishers')['buckets'];
     $data = ['types' => $types, 'subjects' => $subjects, 'publishers' => $publishers, 'type_filters' => $typeFilters, 'subject_filters' => $subjectFilters, 'publisher_filters' => $publisherFilters, 'journals' => $journals, 'pagerfanta' => $pagerfanta, 'page' => 'explore'];
     return $this->render('OjsSiteBundle:Explore:index.html.twig', $data);
 }
示例#4
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 testSearch()
 {
     $client = $this->_getClient();
     $index = new Index($client, 'test');
     $index->create(array(), true);
     $type = new Type($index, 'helloworld');
     $doc = new Document(1, array('id' => 1, 'email' => '*****@*****.**', 'username' => 'hans', 'test' => array('2', '3', '5')));
     $type->addDocument($doc);
     $doc = new Document(2, array('id' => 2, 'email' => '*****@*****.**', 'username' => 'emil', 'test' => array('1', '3', '6')));
     $type->addDocument($doc);
     $doc = new Document(3, array('id' => 3, 'email' => '*****@*****.**', 'username' => 'ruth', 'test' => array('2', '3', '7')));
     $type->addDocument($doc);
     // Refresh index
     $index->refresh();
     $boolQuery = new Bool();
     $termQuery1 = new Term(array('test' => '2'));
     $boolQuery->addMust($termQuery1);
     $resultSet = $type->search($boolQuery);
     $this->assertEquals(2, $resultSet->count());
     $termQuery2 = new Term(array('test' => '5'));
     $boolQuery->addMust($termQuery2);
     $resultSet = $type->search($boolQuery);
     $this->assertEquals(1, $resultSet->count());
     $termQuery3 = new Term(array('username' => 'hans'));
     $boolQuery->addMust($termQuery3);
     $resultSet = $type->search($boolQuery);
     $this->assertEquals(1, $resultSet->count());
     $termQuery4 = new Term(array('username' => 'emil'));
     $boolQuery->addMust($termQuery4);
     $resultSet = $type->search($boolQuery);
     $this->assertEquals(0, $resultSet->count());
 }
示例#6
0
 /**
  * @param string $search
  * @return BoolQuery
  */
 private function getBoolQuery($search)
 {
     $bool = new BoolQuery();
     $text = new Match();
     $text->setField('text', $search);
     $bool->addMust($text);
     return $bool;
 }
示例#7
0
 /**
  * @param  Request $request
  * @param  int $page
  * @return \Symfony\Component\HttpFoundation\Response
  */
 public function indexAction(Request $request, $page = 1)
 {
     $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) : [];
     $userSearcher = $this->get('fos_elastica.index.search.user');
     $userQuery = new Query('*');
     if (!empty($roleFilters) || !empty($subjectFilters) || !empty($journalFilters)) {
         $boolQuery = new Query\Bool();
         foreach ($roleFilters as $role) {
             $match = new Query\Match();
             $match->setField('journalUsers.roles', $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('journalUsers.journal.title', $journal);
             $boolQuery->addMust($match);
         }
         $userQuery->setQuery($boolQuery);
     }
     $roleAgg = new Aggregation\Terms('roles');
     $roleAgg->setField('journalUsers.roles');
     $roleAgg->setOrder('_term', 'asc');
     $roleAgg->setSize(0);
     $userQuery->addAggregation($roleAgg);
     $subjectAgg = new Aggregation\Terms('subjects');
     $subjectAgg->setField('subjects');
     $subjectAgg->setOrder('_term', 'asc');
     $subjectAgg->setSize(0);
     $userQuery->addAggregation($subjectAgg);
     $journalAgg = new Aggregation\Terms('journals');
     $journalAgg->setField('journalUsers.journal.title');
     $journalAgg->setOrder('_term', 'asc');
     $journalAgg->setSize(0);
     $userQuery->addAggregation($journalAgg);
     $adapter = new ElasticaAdapter($userSearcher, $userQuery);
     $pagerfanta = new Pagerfanta($adapter);
     $pagerfanta->setMaxPerPage(20);
     $pagerfanta->setCurrentPage($page);
     $people = $pagerfanta->getCurrentPageResults();
     $roles = $adapter->getResultSet()->getAggregation('roles')['buckets'];
     $subjects = $adapter->getResultSet()->getAggregation('subjects')['buckets'];
     $journals = $adapter->getResultSet()->getAggregation('journals')['buckets'];
     $data = ['people' => $people, 'roles' => $roles, 'subjects' => $subjects, 'journals' => $journals, 'pagerfanta' => $pagerfanta, 'role_filters' => $roleFilters, 'subject_filters' => $subjectFilters, 'journal_filters' => $journalFilters, 'page' => 'ojs_site_people_index'];
     return $this->render('OjsSiteBundle:People:index.html.twig', $data);
 }
示例#8
0
 /**
  * @param Search $search
  * @return Result[]
  */
 public function search(Search $search)
 {
     $bool = new Bool();
     $match = new Match();
     $match->setField('text', $search->getInput());
     $bool->addMust($match);
     $query = new Query();
     $query->setQuery($bool);
     $query->setHighlight(['pre_tags' => ['<mark>'], 'post_tags' => ['</mark>'], 'fields' => ['text' => ['highlight_query' => [$bool->toArray()]]]]);
     $results = $this->getIndex()->search($query, 50)->getResults();
     $this->onSearch($search, $results);
     return $results;
 }
示例#9
0
 /**
  * @param $q
  * @param $locale is verplicht
  * @return mixed
  */
 public function search($q, $locale, $options = null)
 {
     $this->search->addIndex('plant');
     $this->search->addType('plant');
     /* Locale */
     $locale_check = new Match();
     $locale_check->setField("locale", $locale);
     /* The received query */
     $query = new Query($q);
     /* Tie both queries together */
     $bool = new Bool();
     $bool->addShould($q);
     $bool->addShould($locale_check);
     $this->search->setQuery($bool);
     return $this->search->search($q, $options);
 }
 /**
  * Filter search results so only documents that are viewable by the current user will be returned...
  *
  * @param \Elastica\Query\Bool $elasticaQueryBool
  */
 protected function applySecurityContext($elasticaQueryBool)
 {
     $roles = array();
     if (!is_null($this->securityContext)) {
         $user = $this->securityContext->getToken()->getUser();
         if ($user instanceof BaseUser) {
             $roles = $user->getRoles();
         }
     }
     // Anonymous access should always be available for both anonymous & logged in users
     if (!in_array('IS_AUTHENTICATED_ANONYMOUSLY', $roles)) {
         $roles[] = 'IS_AUTHENTICATED_ANONYMOUSLY';
     }
     $elasticaQueryRoles = new \Elastica\Query\Terms();
     $elasticaQueryRoles->setTerms('view_roles', $roles)->setMinimumMatch(1);
     $elasticaQueryBool->addMust($elasticaQueryRoles);
 }
示例#11
0
 /**
  * Perform a search on messages using Elasticsearch
  *
  * @param  string    $query The query string
  * @return Message[] The results of the search
  */
 private function elasticSearch($query)
 {
     $finder = \Service::getContainer()->get('fos_elastica.finder.search');
     $boolQuery = new Bool();
     // We have only stored "active" messages and groups on Elasticsearch's
     // database, so there is no check for that again
     if ($this->player) {
         // Make sure that the parent of the message (i.e. the group that the
         // message belongs into) has the current player as its member
         $recipientQuery = new Term();
         $recipientQuery->setTerm('members', $this->player->getId());
         $parentQuery = new HasParent($recipientQuery, 'group');
         $boolQuery->addMust($parentQuery);
     }
     $fieldQuery = new Match();
     $fieldQuery->setFieldQuery('content', $query)->setFieldFuzziness('content', 'auto');
     $boolQuery->addMust($fieldQuery);
     return $finder->find($boolQuery);
 }
示例#12
0
 /**
  *
  * @ApiDoc(
  *  resource=true,
  *  description="search users in username-email-tags and subjects (accepts regex inputs)",
  *  parameters={
  * {
  *          "name"="q",
  *          "dataType"="string",
  *          "required"="true",
  *          "description"="search term"
  *      }
  *  }
  * )
  * @Get("/search/user")
  *
  * @param  Request $request
  * @return array
  */
 public function getUsersAction(Request $request)
 {
     $q = $request->get('q');
     $search = $this->container->get('fos_elastica.index.search.user');
     $s1 = new Query\Regexp();
     $s1->setValue('username', $q);
     $s2 = new Query\Regexp();
     $s2->setValue('subjects', $q);
     $s3 = new Query\Regexp();
     $s3->setValue('tags', $q);
     $query = new Query\Bool();
     $query->addShould($s1);
     $query->addShould($s2);
     $query->addShould($s3);
     $results = $search->search($query);
     $data = [];
     foreach ($results as $result) {
         $data[] = array_merge(array('id' => $result->getId()), $result->getData());
     }
     return $data;
 }
示例#13
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');
     $searchQuery = new Query('_all');
     $boolQuery = new Query\Bool();
     $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) {
         $data[] = ['id' => $result->getId(), 'text' => $result->getData()['title']];
     }
     return new JsonResponse($data);
 }
示例#14
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;
 }
 /**
  * @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;
 }
 /**
  * Attach a common terms query to $parent with a should.
  * Note that if the all field is not used this can be more restrictive:
  * for the query word1 word2 both words would have to appear in the
  * same field. We cannot use similar techniques like cross_field of
  * QueryString with multiple fields which allows both words to be
  * in different fields.
  *
  * @param \Elastica\Query\Bool $parent
  * @param array $boostedFields of boostedFields
  * @param string $queryString the query
  * @param array $profile the profile
  */
 private function attachCommonTermsClause(\Elastica\Query\Bool $parent, array $boostedFields, $queryString, $profile)
 {
     foreach ($boostedFields as $boostedField) {
         $parent->addShould($this->buildOneCommonTermsClause($boostedField, $queryString, $profile));
     }
 }
 /**
  * getQuery
  *
  * @access private
  * @return \Elastica\Query\AbstractQuery
  */
 private function getQuery()
 {
     if (!$this->queryList) {
         return null;
     }
     if (count($this->queryList) == 1) {
         return current($this->queryList);
     }
     $query = new ElasticaQuery\Bool();
     foreach ($this->queryList as $tmpQuery) {
         $query->addMust($tmpQuery);
     }
     return $query;
 }
 /**
  * Powers full-text-like searches including prefix search.
  *
  * @param string $type
  * @param string $for
  * @return Status(mixed) results from the query transformed by the resultsType
  */
 private function search($type, $for)
 {
     if ($this->nonTextQueries) {
         $bool = new \Elastica\Query\Bool();
         if ($this->query !== null) {
             $bool->addMust($this->query);
         }
         foreach ($this->nonTextQueries as $nonTextQuery) {
             $bool->addMust($nonTextQuery);
         }
         $this->query = $bool;
     }
     if ($this->resultsType === null) {
         $this->resultsType = new FullTextResultsType(FullTextResultsType::HIGHLIGHT_ALL);
     }
     // Default null queries now so the rest of the method can assume it is not null.
     if ($this->query === null) {
         $this->query = new \Elastica\Query\MatchAll();
     }
     $query = new Elastica\Query();
     $query->setParam('_source', $this->resultsType->getSourceFiltering());
     $query->setParam('fields', $this->resultsType->getFields());
     $extraIndexes = array();
     $indexType = $this->pickIndexTypeFromNamespaces();
     if ($this->namespaces) {
         $extraIndexes = $this->getAndFilterExtraIndexes();
         if ($this->needNsFilter($extraIndexes, $indexType)) {
             $this->filters[] = new \Elastica\Filter\Terms('namespace', $this->namespaces);
         }
     }
     // Wrap $this->query in a filtered query if there are any filters
     $unifiedFilter = Filters::unify($this->filters, $this->notFilters);
     if ($unifiedFilter !== null) {
         $this->query = new \Elastica\Query\Filtered($this->query, $unifiedFilter);
     }
     // Call installBoosts right after we're done munging the query to include filters
     // so any rescores installBoosts adds to the query are done against filtered results.
     $this->installBoosts();
     $query->setQuery($this->query);
     $highlight = $this->resultsType->getHighlightingConfiguration($this->highlightSource);
     if ($highlight) {
         // Fuzzy queries work _terribly_ with the plain highlighter so just drop any field that is forcing
         // the plain highlighter all together.  Do this here because this works so badly that no
         // ResultsType should be able to use the plain highlighter for these queries.
         if ($this->fuzzyQuery) {
             $highlight['fields'] = array_filter($highlight['fields'], function ($field) {
                 return $field['type'] !== 'plain';
             });
         }
         if (!empty($this->nonTextHighlightQueries)) {
             // We have some phrase_prefix queries, so let's include them in the
             // generated highlight_query.
             $bool = new \Elastica\Query\Bool();
             if ($this->highlightQuery) {
                 $bool->addShould($this->highlightQuery);
             }
             foreach ($this->nonTextHighlightQueries as $nonTextHighlightQuery) {
                 $bool->addShould($nonTextHighlightQuery);
             }
             $this->highlightQuery = $bool;
         }
         if ($this->highlightQuery) {
             $highlight['highlight_query'] = $this->highlightQuery->toArray();
         }
         $query->setHighlight($highlight);
     }
     if ($this->suggest) {
         $query->setParam('suggest', $this->suggest);
         $query->addParam('stats', 'suggest');
     }
     if ($this->offset) {
         $query->setFrom($this->offset);
     }
     if ($this->limit) {
         $query->setSize($this->limit);
     }
     if ($this->sort != 'relevance') {
         // Clear rescores if we aren't using relevance as the search sort because they aren't used.
         $this->rescore = array();
     }
     if ($this->rescore) {
         // rescore_query has to be in array form before we send it to Elasticsearch but it is way easier to work
         // with if we leave it in query for until now
         $modifiedRescore = array();
         foreach ($this->rescore as $rescore) {
             $rescore['query']['rescore_query'] = $rescore['query']['rescore_query']->toArray();
             $modifiedRescore[] = $rescore;
         }
         $query->setParam('rescore', $modifiedRescore);
     }
     $query->addParam('stats', $type);
     switch ($this->sort) {
         case 'relevance':
             break;
             // The default
         // The default
         case 'title_asc':
             $query->setSort(array('title.keyword' => 'asc'));
             break;
         case 'title_desc':
             $query->setSort(array('title.keyword' => 'desc'));
             break;
         case 'incoming_links_asc':
             $query->setSort(array('incoming_links' => array('order' => 'asc', 'missing' => '_first')));
             break;
         case 'incoming_links_desc':
             $query->setSort(array('incoming_links' => array('order' => 'desc', 'missing' => '_last')));
             break;
         default:
             LoggerFactory::getInstance('CirrusSearch')->warning("Invalid sort type: {sort}", array('sort' => $this->sort));
     }
     $queryOptions = array();
     if ($this->config->get('CirrusSearchMoreAccurateScoringMode')) {
         $queryOptions['search_type'] = 'dfs_query_then_fetch';
     }
     switch ($type) {
         case 'regex':
             $poolCounterType = 'CirrusSearch-Regex';
             $queryOptions['timeout'] = $this->config->getElement('CirrusSearchSearchShardTimeout', 'regex');
             break;
         case 'prefix':
             $poolCounterType = 'CirrusSearch-Prefix';
             $queryOptions['timeout'] = $this->config->getElement('CirrusSearchSearchShardTimeout', 'default');
             break;
         default:
             $poolCounterType = 'CirrusSearch-Search';
             $queryOptions['timeout'] = $this->config->getElement('CirrusSearchSearchShardTimeout', 'default');
     }
     $this->connection->setTimeout($queryOptions['timeout']);
     // Setup the search
     $pageType = $this->connection->getPageType($this->indexBaseName, $indexType);
     $search = $pageType->createSearch($query, $queryOptions);
     foreach ($extraIndexes as $i) {
         $search->addIndex($i);
     }
     $description = "{queryType} search for '{query}'";
     $logContext = array('queryType' => $type, 'query' => $for);
     if ($this->returnQuery) {
         return Status::newGood(array('description' => $this->formatDescription($description, $logContext), 'path' => $search->getPath(), 'params' => $search->getOptions(), 'query' => $query->toArray(), 'options' => $queryOptions));
     }
     // Perform the search
     $searcher = $this;
     $user = $this->user;
     $result = Util::doPoolCounterWork($poolCounterType, $this->user, function () use($searcher, $search, $description, $logContext) {
         try {
             $searcher->start($description, $logContext);
             return $searcher->success($search->search());
         } catch (\Elastica\Exception\ExceptionInterface $e) {
             return $searcher->failure($e);
         }
     }, function ($error, $key, $userName) use($type, $description, $user, $logContext) {
         $forUserName = $userName ? "for {userName} " : '';
         LoggerFactory::getInstance('CirrusSearch')->warning("Pool error {$forUserName}on key {key} during {$description}:  {error}", $logContext + array('userName' => $userName, 'key' => 'key', 'error' => $error));
         if ($error === 'pool-queuefull') {
             if (strpos($key, 'nowait:CirrusSearch:_per_user') === 0) {
                 $loggedIn = $user->isLoggedIn() ? 'logged-in' : 'anonymous';
                 return Status::newFatal("cirrussearch-too-busy-for-you-{$loggedIn}-error");
             }
             if ($type === 'regex') {
                 return Status::newFatal('cirrussearch-regex-too-busy-error');
             }
             return Status::newFatal('cirrussearch-too-busy-error');
         }
         return Status::newFatal('cirrussearch-backend-error');
     });
     if ($result->isOK()) {
         $responseData = $result->getValue()->getResponse()->getData();
         if ($this->returnResult) {
             return Status::newGood(array('description' => $this->formatDescription($description, $logContext), 'path' => $search->getPath(), 'result' => $responseData));
         }
         $result->setResult(true, $this->resultsType->transformElasticsearchResult($this->suggestPrefixes, $this->suggestSuffixes, $result->getValue(), $this->searchContainedSyntax));
         if (isset($responseData['timed_out']) && $responseData['timed_out']) {
             LoggerFactory::getInstance('CirrusSearch')->warning("{$description} timed out and only returned partial results!", $logContext);
             if ($result->getValue()->numRows() === 0) {
                 return Status::newFatal('cirrussearch-backend-error');
             } else {
                 $result->warning('cirrussearch-timed-out');
             }
         }
     }
     return $result;
 }
示例#19
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;
 }