저자: F21
저자: WONG Wing Lun (luiges90@gmail.com)
상속: extends AbstractQuery
예제 #1
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);
 }
예제 #2
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);
 }
예제 #3
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);
 }
예제 #4
0
 /**
  * @group functional
  */
 public function testHasParent()
 {
     $index = $this->_createIndex();
     $shopType = $index->getType('shop');
     $productType = $index->getType('product');
     $mapping = new Mapping();
     $mapping->setParent('shop');
     $productType->setMapping($mapping);
     $shopType->addDocuments(array(new Document('zurich', array('brand' => 'google')), new Document('london', array('brand' => 'apple'))));
     $doc1 = new Document(1, array('device' => 'chromebook'));
     $doc1->setParent('zurich');
     $doc2 = new Document(2, array('device' => 'macmini'));
     $doc2->setParent('london');
     $productType->addDocument($doc1);
     $productType->addDocument($doc2);
     $index->refresh();
     // All documents
     $parentQuery = new HasParent(new MatchAll(), $shopType->getName());
     $search = new Search($index->getClient());
     $results = $search->search($parentQuery);
     $this->assertEquals(2, $results->count());
     $match = new Match();
     $match->setField('brand', 'google');
     $parentQuery = new HasParent($match, $shopType->getName());
     $search = new Search($index->getClient());
     $results = $search->search($parentQuery);
     $this->assertEquals(1, $results->count());
     $result = $results->current();
     $data = $result->getData();
     $this->assertEquals($data['device'], 'chromebook');
 }
예제 #5
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;
 }
예제 #6
0
파일: Query.php 프로젝트: rboyatt/mahara
 /**
  * match query
  *
  * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
  * @param  null|string $field
  * @param  null|string $value
  * @return Match
  */
 public function match($field = null, $value = null)
 {
     if ($field !== null && $value !== null) {
         $match = new Match();
         $match->setParam($field, $value);
         return $match;
     }
     return new Match();
 }
예제 #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
 /**
  * @group functional
  */
 public function testQuery()
 {
     $query = new Query();
     $match = new Match();
     $match->setField('make', 'ford');
     $query->setQuery($match);
     $filter = new Term();
     $filter->setTerm('color', 'green');
     $query->setPostFilter($filter);
     $results = $this->_getTestIndex()->search($query);
     $this->assertEquals(1, $results->getTotalHits());
 }
예제 #9
0
 /**
  * Find all documents where the values are matched in the field. The type option
  * allows you to specify the type of match, can be either phrase or phrase_prefix.
  *
  * The phrase match analyzes the text and creates a phrase query out of the
  * analyzed text.
  *
  * The phrase prefix match is the same as phrase, except that it allows for
  * prefix matches on the last term in the text.
  *
  * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
  *
  * @param string $field The field to search in the index
  * @param string $query The values to search for
  * @param string $type The match type
  * @param bool $fuzzy Set whether the match should be fuzzy
  * @return Query
  */
 public function match($field, $query, $type = 'phrase', $fuzzy = false)
 {
     $match = new Match();
     $match->setFieldQuery($field, $query);
     $match->setFieldType($field, $type);
     if ($fuzzy) {
         $match->setFieldFuzziness($field, 'AUTO');
     }
     $query = $this->newQuery($match);
     $this->query[] = $query;
     return $query;
 }
예제 #10
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;
 }
 /**
  * @group functional
  */
 public function testTypeInsideHasChildSearch()
 {
     $index = $this->_getTestIndex();
     $f = new Match();
     $f->setField('alt.name', 'testname');
     $query = new HasChild($f, 'child');
     $searchQuery = new Query();
     $searchQuery->setQuery($query);
     $searchResults = $index->search($searchQuery);
     $this->assertEquals(1, $searchResults->count());
     $result = $searchResults->current()->getData();
     $expected = array('id' => 'parent2', 'user' => 'parent2', 'email' => '*****@*****.**');
     $this->assertEquals($expected, $result);
 }
예제 #12
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);
 }
예제 #13
0
 public function testContainerSource()
 {
     $client = $this->createClient(array('test_case' => 'ORM'));
     /** @var \FOS\ElasticaBundle\Persister\ObjectPersister $persister */
     $persister = $client->getContainer()->get('fos_elastica.object_persister.index.property_paths_type');
     $obj = new TypeObj();
     $obj->coll = 'Hello';
     $persister->insertOne($obj);
     /** @var \Elastica\Index $elClient */
     $index = $client->getContainer()->get('fos_elastica.index.index');
     $index->flush(true);
     $query = new Match();
     $query->setField('something', 'Hello');
     $search = $index->createSearch($query);
     $this->assertEquals(1, $search->count());
 }
예제 #14
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);
 }
예제 #15
0
 /**
  * @param  Request $request
  * @ApiDoc(
  *                          resource=true,
  *                          description="search journals",
  *                          parameters={
  *                          {
  *                          "name"="q",
  *                          "dataType"="string",
  *                          "required"="true",
  *                          "description"="search term"
  *                          },
  *                          {
  *                          "name"="page",
  *                          "dataType"="integer",
  *                          "required"="false",
  *                          "description"="limit"
  *                          }
  *                          }
  *                          )
  * @Get("/public/search/journal")
  * @return array
  */
 public function getJournalsAction(Request $request)
 {
     $q = $request->get('q');
     $search = $this->container->get('fos_elastica.index.search.journal');
     $match = new Query\Match();
     $match->setField('title', $q);
     $results = $search->search($match);
     $data = [];
     foreach ($results as $result) {
         $data[] = ['id' => $result->getId(), 'text' => $result->getData()['title']];
     }
     return $data;
 }
 public function Addons()
 {
     $list = Addon::get();
     $search = $this->request->getVar('search');
     $type = $this->request->getVar('type');
     $compat = $this->request->getVar('compatibility');
     $tags = $this->request->getVar('tags');
     $sort = $this->request->getVar('sort');
     $view = $this->request->getVar('view');
     if (!$view) {
         $view = 'list';
     }
     if (!in_array($sort, array('name', 'downloads', 'newest'))) {
         $sort = null;
     }
     // Proxy out a search to elastic if any parameters are set.
     if ($search || $type || $compat || $tags) {
         $filter = new BoolAnd();
         $query = new Query();
         $query->setSize(count($list));
         if ($search) {
             $match = new Match();
             $match->setField('_all', $search);
             $query->setQuery($match);
         }
         if ($type) {
             $filter->addFilter(new Term(array('type' => $type)));
         }
         if ($compat) {
             $filter->addFilter(new Terms('compatible', (array) $compat));
         }
         if ($tags) {
             $filter->addFilter(new Terms('tag', (array) $tags));
         }
         if ($type || $compat || $tags) {
             $query->setFilter($filter);
         }
         $list = new ResultList($this->elastica->getIndex(), $query);
         if ($sort) {
             $ids = $list->column('ID');
             if ($ids) {
                 $list = Addon::get()->byIDs($ids);
             } else {
                 $list = new ArrayList();
             }
         }
     } else {
         if (!$sort) {
             $sort = 'downloads';
         }
     }
     switch ($sort) {
         case 'name':
             $list = $list->sort('Name');
             break;
         case 'newest':
             $list = $list->sort('Released', 'DESC');
             break;
         case 'downloads':
             $list = $list->sort('Downloads', 'DESC');
             break;
     }
     $list = new PaginatedList($list, $this->request);
     $list->setPageLength(16);
     return $list;
 }
 public function testMatchFuzzinessType()
 {
     $field = 'test';
     $query = new Match();
     $fuzziness = "AUTO";
     $query->setFieldFuzziness($field, $fuzziness);
     $parameters = $query->getParam($field);
     $this->assertEquals($fuzziness, $parameters['fuzziness']);
     $fuzziness = 0.3;
     $query->setFieldFuzziness($field, $fuzziness);
     $parameters = $query->getParam($field);
     $this->assertEquals($fuzziness, $parameters['fuzziness']);
 }
 /**
  * If there is any boosting to be done munge the the current query to get it right.
  */
 private function installBoosts()
 {
     // Quick note:  At the moment ".isEmpty()" is _much_ faster then ".empty".  Never
     // use ".empty".  See https://github.com/elasticsearch/elasticsearch/issues/5086
     if ($this->sort !== 'relevance') {
         // Boosts are irrelevant if you aren't sorting by, well, relevance
         return;
     }
     $functionScore = new \Elastica\Query\FunctionScore();
     $useFunctionScore = false;
     // Customize score by boosting based on incoming links count
     if ($this->boostLinks) {
         $useFunctionScore = true;
         if ($this->config->getElement('CirrusSearchWikimediaExtraPlugin', 'field_value_factor_with_default')) {
             $functionScore->addFunction('field_value_factor_with_default', array('field' => 'incoming_links', 'modifier' => 'log2p', 'missing' => 0));
         } else {
             $scoreBoostExpression = "log10(doc['incoming_links'].value + 2)";
             $functionScore->addScriptScoreFunction(new \Elastica\Script($scoreBoostExpression, null, 'expression'));
         }
     }
     // Customize score by decaying a portion by time since last update
     if ($this->preferRecentDecayPortion > 0 && $this->preferRecentHalfLife > 0) {
         // Convert half life for time in days to decay constant for time in milliseconds.
         $decayConstant = log(2) / $this->preferRecentHalfLife / 86400000;
         $parameters = array('decayConstant' => $decayConstant, 'decayPortion' => $this->preferRecentDecayPortion, 'nonDecayPortion' => 1 - $this->preferRecentDecayPortion, 'now' => time() * 1000);
         // e^ct where t is last modified time - now which is negative
         $exponentialDecayExpression = "exp(decayConstant * (doc['timestamp'].value - now))";
         if ($this->preferRecentDecayPortion !== 1.0) {
             $exponentialDecayExpression = "{$exponentialDecayExpression} * decayPortion + nonDecayPortion";
         }
         $functionScore->addScriptScoreFunction(new \Elastica\Script($exponentialDecayExpression, $parameters, 'expression'));
         $useFunctionScore = true;
     }
     // Add boosts for pages that contain certain templates
     if ($this->boostTemplates) {
         foreach ($this->boostTemplates as $name => $boost) {
             $match = new \Elastica\Query\Match();
             $match->setFieldQuery('template', $name);
             $filterQuery = new \Elastica\Filter\Query($match);
             $filterQuery->setCached(true);
             $functionScore->addBoostFactorFunction($boost, $filterQuery);
         }
         $useFunctionScore = true;
     }
     // Add boosts for namespaces
     $namespacesToBoost = $this->namespaces ?: MWNamespace::getValidNamespaces();
     if ($namespacesToBoost) {
         // Group common weights together and build a single filter per weight
         // to save on filters.
         $weightToNs = array();
         foreach ($namespacesToBoost as $ns) {
             $weight = $this->getBoostForNamespace($ns);
             $weightToNs[(string) $weight][] = $ns;
         }
         if (count($weightToNs) > 1) {
             unset($weightToNs['1']);
             // That'd be redundant.
             foreach ($weightToNs as $weight => $namespaces) {
                 $filter = new \Elastica\Filter\Terms('namespace', $namespaces);
                 $functionScore->addBoostFactorFunction($weight, $filter);
                 $useFunctionScore = true;
             }
         }
     }
     // Boost pages in a user's language
     $userLang = $this->config->getUserLanguage();
     $userWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'user');
     if ($userWeight) {
         $functionScore->addBoostFactorFunction($userWeight, new \Elastica\Filter\Term(array('language' => $userLang)));
         $useFunctionScore = true;
     }
     // And a wiki's language, if it's different
     $wikiWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'wiki');
     if ($userLang != $this->config->get('LanguageCode') && $wikiWeight) {
         $functionScore->addBoostFactorFunction($wikiWeight, new \Elastica\Filter\Term(array('language' => $this->config->get('LanguageCode'))));
         $useFunctionScore = true;
     }
     if (!$useFunctionScore) {
         // Nothing to do
         return;
     }
     // The function score is done as a rescore on top of everything else
     $this->rescore[] = array('window_size' => $this->config->get('CirrusSearchFunctionRescoreWindowSize'), 'query' => array('rescore_query' => $functionScore, 'query_weight' => 1.0, 'rescore_query_weight' => 1.0, 'score_mode' => 'multiply'));
 }
예제 #19
0
 public function testMatchPhrasePrefix()
 {
     $client = $this->_getClient();
     $index = $client->getIndex('test');
     $index->create(array(), true);
     $type = $index->getType('test');
     $doc = new Document(1, array('name' => 'Basel-Stadt'));
     $type->addDocument($doc);
     $doc = new Document(2, array('name' => 'New York'));
     $type->addDocument($doc);
     $doc = new Document(3, array('name' => 'New Hampshire'));
     $type->addDocument($doc);
     $doc = new Document(4, array('name' => 'Basel Land'));
     $type->addDocument($doc);
     $index->refresh();
     $field = 'name';
     $type = 'phrase_prefix';
     $query = new Match();
     $query->setFieldQuery($field, 'New');
     $query->setFieldType($field, $type);
     $resultSet = $index->search($query);
     $this->assertEquals(2, $resultSet->count());
 }
예제 #20
0
 /**
  * @Extra\Route(
  *      "/api/twitter/aggregate/{keywords}/{since}/{until}",
  *      name="weaving_the_web_dashboard_people_talking_about",
  *      requirements={"keywords": "[-,%\+a-zA-Z0-9]+"}
  * )
  * @Extra\Method({"GET"})
  *
  * @Extra\Cache(expires="+1 week", public="true")
  *
  * @param $keywords
  * @param \DateTime $since
  * @param \DateTime $until
  * @return \Symfony\Component\HttpFoundation\Response
  */
 public function aggregateFilteredTermsAction($keywords, \DateTime $since, \DateTime $until)
 {
     $termsAggregationName = 'screen_name_aggregations';
     $filteredAggregationName = 'screen_name_aggregated_in_range';
     $timeSeries = [];
     $screenNamesAggregations = [];
     $keywords = explode(',', $keywords);
     $keywordIndex = 0;
     if (count($keywords) > 5) {
         $keywords = array_slice($keywords, 0, 5);
     }
     $fingerprint = sha1(serialize([$keywords, $since, $until]));
     $aggregationsPath = sprintf(__DIR__ . '/../Resources/json/aggregations/%s.json', $fingerprint);
     if (file_exists($aggregationsPath)) {
         $content = unserialize(base64_decode(file_get_contents($aggregationsPath)));
         return new JsonResponse($content);
     }
     $lastYear = $until->format('Y');
     foreach ($keywords as $keyword) {
         $match = new Query\Match();
         $match->setField('text', $keyword);
         $query = new Query($match);
         $aggregation = new Aggregation();
         $timeSeries[$keywordIndex] = [];
         foreach (range($since->format('Y'), $lastYear) as $year) {
             if ($year === $lastYear) {
                 $lastMonth = min(12, $until->format('m'));
             } else {
                 $lastMonth = 12;
             }
             foreach (range(1, $lastMonth) as $month) {
                 if ($year === $lastYear && $month == $lastMonth) {
                     $days = $until->format('d');
                 } else {
                     $days = cal_days_in_month(CAL_GREGORIAN, $month, $year);
                 }
                 foreach (range(1, $days) as $day) {
                     $termsAggregation = $aggregation->terms($termsAggregationName);
                     $termsAggregation->setField('screenName');
                     $termsAggregation->setSize(30);
                     $yearMonthDay = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-' . str_pad($day, 2, '0', STR_PAD_LEFT);
                     $startDate = new \DateTime($yearMonthDay . ' 0:00');
                     $endDate = new \DateTime($yearMonthDay . ' 23:59');
                     $range = new Range('createdAt', ['gte' => $startDate->format('c'), 'lte' => $endDate->format('c')]);
                     $rangeFilterAggregation = $aggregation->filter($filteredAggregationName, $range);
                     $rangeFilterAggregation->addAggregation($termsAggregation);
                     $query->addAggregation($rangeFilterAggregation);
                     $query->setSize(100);
                     $searchIndex = $this->container->getParameter('twitter_search_index');
                     /** @var \FOS\ElasticaBundle\Elastica\Index $index */
                     $index = $this->get('fos_elastica.index.' . $searchIndex);
                     $userStatusType = $index->getType('user_status');
                     $aggregations = $userStatusType->search($query)->getAggregations();
                     foreach ($aggregations[$filteredAggregationName][$termsAggregationName]['buckets'] as $bucket) {
                         $screenNamesAggregations[$yearMonthDay][$keywordIndex][$bucket['key']] = $bucket['doc_count'];
                     }
                     $timeSeries[$keywordIndex][] = ['date' => $yearMonthDay, 'mentions' => $aggregations[$filteredAggregationName]['doc_count']];
                 }
             }
         }
         $keywordIndex++;
     }
     $contents = ['time_series' => $timeSeries, 'screen_name_aggregations' => $screenNamesAggregations];
     file_put_contents($aggregationsPath, base64_encode(serialize($contents)));
     return new JsonResponse($contents);
 }
 /**
  * @group unit
  */
 public function testConstruct()
 {
     $match = new Match(null, 'values');
     $this->assertEquals(array('match' => array()), $match->toArray());
     $match = new Match('field', null);
     $this->assertEquals(array('match' => array()), $match->toArray());
     $match1 = new Match('field', 'values');
     $match2 = new Match();
     $match2->setField('field', 'values');
     $this->assertEquals($match1->toArray(), $match2->toArray());
 }
예제 #22
0
 /**
  * @param  Query\Match $query
  * @param $key
  * @param $value
  * @throws \ErrorException
  */
 public function applyFilter(Query\Match &$query, $key, $value)
 {
     switch ($key) {
         case 'journal':
             $query->setField('journal.id', $value);
             break;
         case 'author':
             $query->setField('articleAuthors.author.id', $value);
             break;
         case 'institution':
             $query->setField('institution.institution_type.id', $value);
             break;
         case 'subject':
             $query->setField('subjects.id', $value);
             break;
         default:
             throw new \ErrorException("Filter not exist. allowed filters: journal, author, institution, subject");
     }
 }