public function testFuzzyWithFacets()
 {
     $index = $this->_createIndex();
     $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' => 'Baden'));
     $type->addDocument($doc);
     $doc = new Document(4, array('name' => 'Baden Baden'));
     $type->addDocument($doc);
     $index->refresh();
     $field = 'name';
     $fuzzyQuery = new Fuzzy();
     $fuzzyQuery->setField($field, 'Baden');
     $facet = new \Elastica\Facet\Terms('test');
     $facet->setField('name');
     $query = new \Elastica\Query($fuzzyQuery);
     $query->addFacet($facet);
     $resultSet = $index->search($query);
     // Assert query worked ok
     $this->assertEquals(2, $resultSet->count());
     // Check Facets
     $this->assertTrue($resultSet->hasFacets());
     $facets = $resultSet->getFacets();
     $this->assertEquals(2, $facets['test']['total']);
 }
 /**
  * adds current attribute facet condition to product collection
  *
  * @return Hackathon_ElasticgentoCore_Model_Catalog_Layer_Filter_Attribute
  */
 public function addFacetToCollection()
 {
     $facet = new \Elastica\Facet\Terms($this->getAttributeModel()->getAttributeCode());
     $facet->setField($this->getAttributeModel()->getAttributeCode());
     $facet->setSize(10);
     $this->getLayer()->getProductCollection()->addFacet($facet);
     return $this;
 }
Beispiel #3
0
 /**
  *
  * @see FacetInterface::getFacet
  */
 public function getFacet($fieldName, \Elastica\Filter\AbstractFilter $mainFilter)
 {
     $rawFieldName = $this->getRawFieldName($fieldName);
     $mainFilter = $this->prepareMainFilter($mainFilter, $rawFieldName);
     $facet = new \Elastica\Facet\Terms($fieldName);
     $facet->setField($rawFieldName);
     $facet->setSize($this->options['size']);
     $facet->setFilter($mainFilter);
     return $facet;
 }
Beispiel #4
0
 /**
  * Adds facet condition to product collection.
  *
  * @return Hackathon_ElasticgentoCore_Model_Catalog_Layer_Filter_Category
  * @todo add filter for current category childen
  */
 public function addFacetToCollection()
 {
     /** @var $category Mage_Catalog_Model_Category */
     #$category = $this->getCategory();
     #$childrenCategories = $category->getChildrenCategories();
     /** @todo refactor */
     #$useFlat = (bool)Mage::getStoreConfig('catalog/frontend/flat_catalog_category');
     #$categories = ($useFlat) ? array_keys($childrenCategories) : array_keys($childrenCategories->toArray());
     $facet = new \Elastica\Facet\Terms('categories');
     $facet->setField('categories');
     $facet->setSize(10);
     $this->getLayer()->getProductCollection()->addFacet($facet);
     return $this;
 }
Beispiel #5
0
 /**
  *   To respect the design, 3 searches will be executed:
  *       1st:    retrieves the main facet (Text / Media / Portfolio / Users / Group) and the count for each of them
  *       2nd:    - retrieves the results of the first non empty facet term for display in the tab
  *               - retrieves the secondary facet to enable / disable the filter items
  *       3nd:    - retrieves the results with all filters applied
  * @param unknown $query_string
  * @param unknown $limit
  * @param unknown $offset
  * @param unknown $options
  * @param unknown $mainfacetterm
  * @param unknown $USER
  * @return multitype:number boolean unknown Ambigous <boolean, NULL> Ambigous <boolean, unknown> multitype:multitype:string number   Ambigous <string, unknown> |multitype:multitype:
  */
 public static function search($query_string, $limit, $offset, $options, $mainfacetterm, $USER)
 {
     $result = array('count' => 0, 'limit' => $limit, 'offset' => $offset, 'data' => false, 'selected' => isset($mainfacetterm) && strlen($mainfacetterm) > 0 ? $mainfacetterm : false, 'totalresults' => 0, 'facets' => array(array('term' => "Text", 'count' => 0, 'display' => "Text"), array('term' => "Media", 'count' => 0, 'display' => "Media"), array('term' => "Portfolio", 'count' => 0, 'display' => "Portfolio"), array('term' => "User", 'count' => 0, 'display' => "Users"), array('term' => "Group", 'count' => 0, 'display' => "Group")), 'content-filter' => array(array('term' => "all", 'count' => 0, 'display' => "All"), array('term' => "Audio", 'count' => 0, 'display' => "Audio"), array('term' => "Comment", 'count' => 0, 'display' => "Comment"), array('term' => "Document", 'count' => 0, 'display' => "Document"), array('term' => "Folder", 'count' => 0, 'display' => "Folder"), array('term' => "Forum", 'count' => 0, 'display' => "Forum"), array('term' => "Forumpost", 'count' => 0, 'display' => "Forum post"), array('term' => "Image", 'count' => 0, 'display' => "Image"), array('term' => "Journal", 'count' => 0, 'display' => "Journal"), array('term' => "Journalentry", 'count' => 0, 'display' => "Journal entry"), array('term' => "Note", 'count' => 0, 'display' => "Note"), array('term' => "Plan", 'count' => 0, 'display' => "Plan"), array('term' => "Profile", 'count' => 0, 'display' => "Profile"), array('term' => "Resume", 'count' => 0, 'display' => "Résumé"), array('term' => "Video", 'count' => 0, 'display' => "Video"), array('term' => "Wallpost", 'count' => 0, 'display' => "Wall post"), array('term' => "Collection", 'count' => 0, 'display' => "Collection"), array('term' => "Page", 'count' => 0, 'display' => "Page")), 'content-filter-selected' => isset($options['secfacetterm']) && strlen($options['secfacetterm']) > 0 ? $options['secfacetterm'] : 'all', 'owner-filter' => array(array('term' => "all", 'count' => 0, 'display' => "All"), array('term' => "me", 'count' => 0, 'display' => "Me"), array('term' => "others", 'count' => 0, 'display' => "Others")), 'owner-filter-selected' => isset($options['owner']) && strlen($options['owner']) > 0 ? $options['owner'] : 'all', 'tagsonly' => isset($options['tagsonly']) && $options['tagsonly'] == true ? true : Null, 'sort' => isset($options['sort']) && strlen($options['sort']) > 0 ? $options['sort'] : 'score', 'license' => isset($options['license']) && strlen($options['license']) > 0 ? $options['license'] : 'all');
     if (strlen($query_string) <= 0) {
         return $result;
     }
     //      1- Get main facet
     // ------------------------------------------------------------------------------------------
     $records = array();
     $elasticaClient = PluginSearchElasticsearch::make_client();
     $elasticaIndex = $elasticaClient->getIndex(get_config_plugin('search', 'elasticsearch', 'indexname'));
     $elasticaQueryString = new \Elastica\Query\QueryString();
     $elasticaAnalyzer = get_config_plugin('search', 'elasticsearch', 'analyzer');
     $elasticaQueryString->setAnalyzer($elasticaAnalyzer);
     $elasticaQueryString->setDefaultOperator('AND');
     $elasticaQueryString->setQuery($query_string);
     // if tags only => set fields to tags
     if ($result['tagsonly'] === true) {
         $elasticaQueryString->setFields(array('tags'));
     }
     // Create the $elasticaQuery object
     $elasticaQuery = new \Elastica\Query();
     $elasticaQuery->setFrom($offset);
     $elasticaQuery->setLimit($limit);
     $elasticaQuery->setQuery($elasticaQueryString);
     $elasticaFilterAnd = new \Elastica\Filter\BoolAnd();
     // Apply ACL filters
     $elasticaFilterACL = new ElasticsearchFilterAcl($USER);
     $elasticaFilterAnd->addFilter($elasticaFilterACL);
     $elasticaQuery->setFilter($elasticaFilterAnd);
     // Define a new facet: mainFacetTerm  - WARNING: don't forget to apply the same filter to the facet
     $elasticaFacet = new \Elastica\Facet\Terms('mainFacetTerm');
     $elasticaFacet->setField('mainfacetterm');
     $elasticaFacet->setOrder('count');
     $elasticaFacet->setFilter($elasticaFilterAnd);
     $elasticaQuery->addFacet($elasticaFacet);
     $elasticaResultSet = $elasticaIndex->search($elasticaQuery);
     $result['totalresults'] = $elasticaResultSet->getTotalHits();
     $elasticaFacets = $elasticaResultSet->getFacets();
     $facets = self::process_facets($elasticaFacets['mainFacetTerm']['terms']);
     if (count($facets) == 0) {
         return $result;
     }
     array_walk($result['facets'], 'self::process_tabs', $facets);
     if ($result['selected'] === false || $facets[$result['selected']] == 0) {
         $result['selected'] = self::get_selected_facet($result['facets']);
     }
     //      2- Retrieve results of selected facet
     // ------------------------------------------------------------------------------------------
     $elasticaFilterType = new \Elastica\Filter\Term(array('mainfacetterm' => $result['selected']));
     $elasticaFilterAnd->addFilter($elasticaFilterType);
     $elasticaQuery->setFilter($elasticaFilterAnd);
     // Define a new facet: secFacetTerm  - WARNING: don't forget to apply the same filter to the facet
     $elasticaFacet = new \Elastica\Facet\Terms('secFacetTerm');
     $elasticaFacet->setField('secfacetterm');
     $elasticaFacet->setOrder('count');
     $elasticaFacet->setFilter($elasticaFilterAnd);
     $elasticaQuery->addFacet($elasticaFacet);
     // Sorting
     // Sorting is defined on a per field level, so we must make sure the field exists in the mapping
     $sort = explode('_', $result['sort']);
     if ($sort[0] == 'score') {
         $sort[0] = '_score';
     }
     // set the second column to sort by the score (to break any 'ties').
     $elasticaQuery->setSort(array(array($sort[0] => array('order' => isset($sort[1]) ? $sort[1] : 'desc')), array('_score' => array('order' => 'desc'))));
     $elasticaResultSet = $elasticaIndex->search($elasticaQuery);
     $result['count'] = $elasticaResultSet->getTotalHits();
     $elasticaFacets = $elasticaResultSet->getFacets();
     $facets = $elasticaFacets['secFacetTerm']['terms'];
     $facets = self::process_facets($elasticaFacets['secFacetTerm']['terms']);
     array_walk($result['content-filter'], 'self::process_tabs', $facets);
     // set the count of "all" to the total hits
     $result['content-filter'][0]['count'] = $result['count'];
     //      3- Apply filters and retrieve final results
     // ------------------------------------------------------------------------------------------
     // Apply Content filter if different from "all"
     if ($result['content-filter-selected'] != 'all') {
         $elasticaFilterContent = new \Elastica\Filter\Term(array('secfacetterm' => $result['content-filter-selected']));
         $elasticaFilterAnd->addFilter($elasticaFilterContent);
     }
     // Apply Owner filter if different from "all"
     if ($result['owner-filter-selected'] != 'all') {
         $uid = $USER->get('id');
         $elasticaFilterOwner = new \Elastica\Filter\Term(array('owner' => $uid));
         if ($result['owner-filter-selected'] == 'others') {
             $elasticaFilterOwner = new \Elastica\Filter\BoolNot($elasticaFilterOwner);
         }
         $elasticaFilterAnd->addFilter($elasticaFilterOwner);
     }
     // Apply license filter if different from "all"
     if ($result['license'] != 'all') {
         $elasticaFilterLicense = new \Elastica\Filter\Term(array('license' => $result['license']));
         $elasticaFilterAnd->addFilter($elasticaFilterLicense);
     }
     $elasticaQuery->setFilter($elasticaFilterAnd);
     $elasticaResultSet = $elasticaIndex->search($elasticaQuery);
     $elasticaResults = $elasticaResultSet->getResults();
     $result['count'] = $elasticaResultSet->getTotalHits();
     foreach ($elasticaResults as $elasticaResult) {
         $tmp = array();
         $tmp['type'] = $elasticaResult->getType();
         $ES_class = 'ElasticsearchType_' . $tmp['type'];
         $tmp = $tmp + $elasticaResult->getData();
         // Get all the data from the DB table
         $dbrec = $ES_class::getRecordDataById($tmp['type'], $tmp['id']);
         if ($dbrec) {
             $tmp['db'] = $dbrec;
             $tmp['db']->deleted = false;
         } else {
             // If the record has been deleted, so just pass the cached data
             // from the search result. Let the template decide how to handle
             // it.
             $tmp['db'] = (object) $tmp;
             $tmp['db']->deleted = true;
         }
         $records[] = $tmp;
     }
     $result['data'] = $records;
     return $result;
 }
 /**
  * @param AbstractElasticaSearcher $searcher
  * @param Request                  $request
  * @param RenderContext            $context
  */
 protected function applySearchParams(AbstractElasticaSearcher $searcher, Request $request, RenderContext $context)
 {
     // Retrieve the search parameters
     $queryString = trim($request->query->get('query'));
     $queryType = $request->query->get('type');
     $lang = $request->getLocale();
     $context['q_query'] = $queryString;
     $context['q_type'] = $queryType;
     $searcher->setData($this->sanitizeSearchQuery($queryString))->setContentType($queryType)->setLanguage($lang);
     // Facets
     $query = $searcher->getQuery();
     $facetTerms = new \Elastica\Facet\Terms('type');
     $facetTerms->setField('type');
     $query->addFacet($facetTerms);
     // Aggregations
     $termsAggregation = new Terms('type');
     $termsAggregation->setField('type');
     $query->addAggregation($termsAggregation);
 }
 /**
  * get attribute sets for current collection
  *
  * @return mixed
  */
 public function getSetIds()
 {
     if (false == $this->isLoaded()) {
         $tmpSize = $this->getPageSize();
         $this->setPageSize(0);
         $facet = new \Elastica\Facet\Terms('attribute_set_id');
         $facet->setField('attribute_set_id');
         $facet->setSize(10);
         $this->addFacet($facet);
         $this->load();
         $this->removeFacet($facet->getName());
         $this->setPageSize($tmpSize);
         $this->_setIsLoaded(false);
     }
     if (0 == count($this->_setIds)) {
         foreach ($this->_responseFacets['attribute_set_id']['terms'] as $term) {
             $this->_setIds[$term['term']] = $term['term'];
         }
     }
     return $this->_setIds;
 }
Beispiel #8
0
 /**
  * @param string $q
  * @param array $params
  * @return array
  */
 protected function _getAllFacets($q, array $params)
 {
     $facets = array();
     $hasStats = isset($params['stats']) && isset($params['stats']['fields']) && !empty($params['stats']['fields']);
     if ($hasStats) {
         foreach ($params['stats']['fields'] as $field) {
             $facet = new \Elastica\Facet\Statistical($field);
             $facet->setParam('field', $field);
             $facets[] = $facet;
         }
     }
     if (isset($params['facets']) && !empty($params['facets'])) {
         $properties = $this->_getIndexProperties();
         $filters = isset($params['filters']) ? $params['filters'] : array();
         foreach ($params['facets'] as $field => $conds) {
             $queryFilter = null;
             if (array_key_exists($field, $filters)) {
                 $_params = $params;
                 #AM unset comment out for ATM (Custom Code). Need to test for other clients
                 //  unset($_params['filters'][$field]);
                 $queryFilter = new \Elastica\Filter\Query($this->_getFilteredQuery($q, $_params));
             }
             if (null === $conds) {
                 // Terms Facet
                 if (!$hasStats && array_key_exists($field, $properties)) {
                     $facet = new \Elastica\Facet\Terms($field);
                     if ($properties[$field]['type'] == 'multi_field') {
                         $field .= '.untouched';
                     }
                     $facet->setField($field)->setAllTerms(true)->setSize($this->getFacetsMaxSize());
                     if ($queryFilter) {
                         $facet->setGlobal()->setFilter($queryFilter);
                     }
                     $facets[] = $facet;
                 }
             } elseif (is_array($conds)) {
                 if (isset($conds[0]['from']) && isset($conds[0]['to'])) {
                     if (!$hasStats) {
                         // Range Facet
                         $facet = new \Elastica\Facet\Range($field);
                         $facet->setField($field)->setRanges($this->_helper->_prepareRanges($conds));
                         $facets[] = $facet;
                     }
                 } else {
                     foreach ($conds as $cond) {
                         // Query Facet
                         $query = $this->_helper->_prepareQuery($field, $cond);
                         $facet = new \Elastica\Facet\Query($query);
                         $facet->setQuery(new \Elastica\Query\QueryString($query));
                         if ($queryFilter) {
                             $facet->setGlobal()->setFilter($queryFilter);
                         }
                         $facets[] = $facet;
                     }
                 }
             }
         }
     }
     return $facets;
 }
 /**
  *
  * Add facets on elastic query object
  * @param \Elastica\Query $query
  * @param array $options
  * @param \Elastica\Filter\AbstractFilter $mainFilter
  */
 protected function addFacets(\Elastica\Query $query, $options = array(), \Elastica\Filter\AbstractFilter $mainFilter = null)
 {
     // module facet (note: would be less confusing to give another name instead of _type)
     if (!empty($options['apply_module_facet'])) {
         $typeFacet = new \Elastica\Facet\Terms('_type');
         $typeFacet->setField('_type');
         // need to add filter for facet too
         if (isset($mainFilter)) {
             $typeFacet->setFilter($mainFilter);
         }
         $query->addFacet($typeFacet);
     }
     // handle secondary facets
     $this->facetHandler->addFacets($query, $options, $mainFilter);
 }
 public function search($queryString, $opts, $highlight)
 {
     $query = new \Elastica\Query();
     list($searchQuery, $highlights) = $this->parseQueryString($queryString, $opts);
     $query->setQuery($searchQuery);
     $language = new \Elastica\Facet\Terms('language');
     $language->setField('language');
     $language->setSize(500);
     $query->addFacet($language);
     $group = new \Elastica\Facet\Terms('group');
     $group->setField('group');
     // Would like to prioritize the top level groups and not show subgroups
     // if the top group has only few hits, but that doesn't seem to be possile.
     $group->setSize(500);
     $query->addFacet($group);
     $query->setSize($opts['limit']);
     $query->setFrom($opts['offset']);
     // BoolAnd filters are executed in sequence per document. Bool filters with
     // multiple must clauses are executed by converting each filter into a bit
     // field then anding them together. The latter is normally faster if either
     // of the subfilters are reused. May not make a difference in this context.
     $filters = new \Elastica\Filter\Bool();
     $language = $opts['language'];
     if ($language !== '') {
         $languageFilter = new \Elastica\Filter\Term();
         $languageFilter->setTerm('language', $language);
         $filters->addMust($languageFilter);
     }
     $group = $opts['group'];
     if ($group !== '') {
         $groupFilter = new \Elastica\Filter\Term();
         $groupFilter->setTerm('group', $group);
         $filters->addMust($groupFilter);
     }
     // Check that we have at least one filter to avoid invalid query errors.
     if ($language !== '' || $group !== '') {
         $query->setPostFilter($filters);
     }
     list($pre, $post) = $highlight;
     $query->setHighlight(array('pre_tags' => array($pre), 'post_tags' => array($post), 'fields' => $highlights));
     try {
         return $this->getType()->getIndex()->search($query);
     } catch (\Elastica\Exception\ExceptionInterface $e) {
         throw new TTMServerException($e->getMessage());
     }
 }