Source of file ElasticaSearchController.php
Size: 10,060 Bytes - Last Modified: 2021-12-23T10:07:43+00:00
/var/www/docs.ssmods.com/process/src/src/ElasticaSearchController.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 | <?php namespace Symbiote\ElasticSearch; use ArrayObject; use Elastica\ResultSet; use SilverStripe\Core\Extension; use SilverStripe\Forms\Form; use SilverStripe\Control\HTTP; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\Convert; use SilverStripe\Forms\CheckboxSetField; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldGroup; use SilverStripe\ORM\FieldType\DBVarchar; /** * * * @author marcus */ class ElasticaSearchController extends Extension { public function updateExtensibleSearchForm(Form $form) { $page = $this->owner->data(); if (!$page) { return; } $filters = $page->UserFilters->getValues(); if ($filters) { $filterFieldValues = []; $defaults = $page->DefaultFilters->getValues() ?? []; $filterOptions = array_keys($filters); if (count($defaults)) { foreach ($defaults as $field => $value) { $index = array_search($field . ':' . $value, $filterOptions); if ($index !== false) { $filterFieldValues[] = $index; } } } $cbsf = CheckboxSetField::create('UserFilter', '', array_values($filters)); // $filterFieldValues = array_keys(array_values($filters)); //To set UserFilter default value on Search page if (isset($_GET['action_getSearchResults']) && isset($_GET['UserFilter'])) { $filterFieldValues = $_GET['UserFilter']; } $cbsf->setValue($filterFieldValues); $form->Fields()->push($cbsf); } $existingSearch = singleton(ElasticaSearchEngine::class)->getCurrentResults(); if ( $existingSearch && isset($existingSearch['Aggregations']) && count($existingSearch['Aggregations']) ) { $request = $this->owner->getRequest(); $aggregation = $request->getVar('aggregation'); $aggregationGroup = FieldGroup::create('AggregationOptions'); foreach ($existingSearch['Aggregations'] as $facetType) { $currentLabel = null; $filterField = null; $options = []; foreach ($facetType as $facetItem) { if (!$currentLabel) { $currentLabel = $facetItem->type; $filterField = $facetItem->field; } $options[$facetItem->key] = $facetItem->key . ($page->ShowFacetCount ? ' (' . $facetItem->doc_count . ')' : ''); } if (count($options)) { $fieldName = "aggregation[$filterField]"; $values = isset($aggregation[$filterField]) ? $aggregation[$filterField] : []; if ($page->FacetStyle === 'Dropdown') { $aggregationGroup->push( DropdownField::create("", $currentLabel, $options) ->addExtraClass('facet-dropdown') ->setEmptyString(' ') ->setValue($values) ); } else if ($page->FacetStyle === 'Checkbox') { $aggregationGroup->push( CheckboxSetField::create("aggregation[$filterField]", $currentLabel, $options) ->addExtraClass('facet-checkbox') ->setValue($values) ); } } } $form->Fields()->push($aggregationGroup); } } public function getAggregationFilters() { $request = $this->owner->getRequest(); // Determine the selected facets/aggregations. $aggregation = $request->getVar('aggregation'); $aggregations = null; if ($aggregation && is_array($aggregation) && count($aggregation)) { $aggregations = ArrayList::create(); // Determine the display title for an aggregation. $facets = $this->owner->data()->facetFieldMapping(); foreach ($aggregation as $type => $filter) { if (!$filter) { continue; } $bucket = array( 'key' => is_array($filter) ? implode(', ', $filter) : $filter, 'type' => (isset($facets[$type]) ? $facets[$type] : $type) ); // Determine the redirect to be used when using the facet/aggregation. $vars = $request->getVars(); unset($vars['url']); unset($vars['aggregation']); $link = $this->owner->data()->Link('getForm'); foreach ($vars as $var => $value) { $link = HTTP::setGetVar($var, $value, $link); } $bucket['link'] = $link; $aggregations->push(ArrayData::create($bucket)); } } return $aggregations; } public function isSearchFiltered() { /** @var HTTPRequest */ $request = $this->owner->getRequest(); if ($request->requestVar('aggregation')) { return true; } } /** * Returns a set of _aggregated_ results, ie those aggregated * by a certain field */ public function AggregatedResults($fieldName) { /** @var HTTPRequest */ $request = $this->owner->getRequest(); if ($request->requestVar('aggregation')) { return; } /** @var ResultSet */ $existingSearch = singleton(ElasticaSearchEngine::class)->getCurrentElasticResult(); if (!$existingSearch) { return; } $agg = $existingSearch->getAggregation($fieldName); $overallList = []; if ($agg && isset($agg['buckets'])) { foreach ($agg['buckets'] as $bucket) { if (!isset($bucket['key']) || !strlen($bucket['key'])) { continue; } if ( !isset($bucket['top_facet_docs']['hits']['hits']) || count($bucket['top_facet_docs']['hits']['hits']) === 0 ) { continue; } $title = $bucket['key']; $resultList = new AggregateResultList($bucket['top_facet_docs']['hits']['hits']); $vars = $request->getVars(); unset($vars['url']); unset($vars['aggregation']); $link = $this->owner->data()->Link('getForm'); $vars['aggregation'] = [$fieldName => $title]; foreach ($vars as $var => $value) { $link = HTTP::setGetVar($var, $value, $link); } $overallList[] = ArrayData::create([ 'Title' => $title, 'Children' => $resultList->toArrayList(), 'Link' => $link, ]); } } return ArrayList::create($overallList); } /** * Process and render search results * * @deprecated Since 2018 or thereabouts. Doesn't work! * @return array */ public function getSearchResults($data = null, $form = null) { $request = $this->owner->getRequest(); $query = $this->owner->data()->getResults(); /* @var $query SilverStripe\Elastica\ResultList */ // Determine the selected facets/aggregations to apply. $aggregation = $request->getVar('aggregation'); if ($aggregation && is_array($aggregation)) { // HACK sorry $q = $query->getQuery()->getQuery()->getParam('query'); foreach ($aggregation as $field => $value) { $q->addFilter(new Query\QueryString("{$field}:\"{$value}\"")); } } // Determine the query sorting. $sortBy = $request->getVar('SortBy') ? $request->getVar('SortBy') : $this->owner->SortBy; $sortDirection = $request->getVar('SortDirection') ? $request->getVar('SortDirection') : $this->owner->SortDirection; $query->getQuery()->setSort(array( $sortBy => strtolower($sortDirection) )); $term = $request->getVar('Search') ? Convert::raw2xml($request->getVar('Search')) : ''; $message = ''; try { $results = $query ? $query->getDataObjects( $this->owner->ResultsPerPage, $request->getVar('start') ? $request->getVar('start') : 0 ) : ArrayList::create(); } catch (Exception $ex) { error_log($ex->getMessage()); $message = 'Search failed'; $query = null; $results = ArrayList::create(); } $elapsed = '< 0.001'; $count = ($query && ($total = $query->getTotalResults())) ? $total : 0; if ($query) { $resultData = array( 'TotalResults' => $count ); $time = $query->getTimeTaken(); if ($time) { $elapsed = $time / 1000; } } else { $resultData = array(); } $data = new ArrayObject(array( 'Message' => $message, 'Results' => $results, 'Count' => $count, 'Query' => DBVarchar::create_field('Varchar', $term), 'Title' => $this->owner->data()->Title, 'ResultData' => ArrayData::create($resultData), 'TimeTaken' => $elapsed, 'RawQuery' => $query ? json_encode($query->getQuery()->toArray()) : '' )); $this->owner->extend('updateSearchResults', $data); return $data->getArrayCopy(); } } |