Exemplo n.º 1
0
 function find(Search_Query_Interface $query, $resultStart, $resultCount)
 {
     $builder = new Search_Elastic_QueryBuilder();
     $queryPart = $builder->build($query->getExpr());
     $builder = new Search_Elastic_OrderBuilder();
     $orderPart = $builder->build($query->getSortOrder());
     $builder = new Search_Elastic_FacetBuilder();
     $facetPart = $builder->build($query->getFacets());
     $fullQuery = array_merge($queryPart, $orderPart, $facetPart, array("from" => $resultStart, "size" => $resultCount, "highlight" => array("fields" => array('contents' => array("number_of_fragments" => 5)))));
     $result = $this->connection->search($this->index, $fullQuery, $resultStart, $resultCount);
     $hits = $result->hits;
     $entries = array_map(function ($entry) {
         $data = (array) $entry->_source;
         if (isset($entry->highlight->contents)) {
             $data['_highlight'] = implode('...', $entry->highlight->contents);
         } else {
             $data['_highlight'] = '';
         }
         return $data;
     }, $hits->hits);
     $resultSet = new Search_Elastic_ResultSet($entries, $hits->total, $resultStart, $resultCount);
     $reader = new Search_Elastic_FacetReader($result);
     foreach ($query->getFacets() as $facet) {
         if ($filter = $reader->getFacetFilter($facet)) {
             $resultSet->addFacetFilter($filter);
         }
     }
     return $resultSet;
 }
Exemplo n.º 2
0
 function testBuildMultipleFacets()
 {
     $builder = new Search_Elastic_FacetBuilder(8);
     $this->assertEquals(array('facets' => array('categories' => array('terms' => array('field' => 'categories', 'size' => 8)), 'deep_categories' => array('terms' => array('field' => 'deep_categories', 'size' => 15)))), $builder->build(array(Search_Query_Facet_Term::fromField('categories'), Search_Query_Facet_Term::fromField('deep_categories')->setCount(15))));
 }
Exemplo n.º 3
0
 function find(Search_Query_Interface $query, $resultStart, $resultCount)
 {
     global $prefs;
     /**
      * Sorted search size adjustment (part 1) - This is used to trim large data sets that need
      * to be sorted by date. Sorting can take a very long time on these data sets and the data
      * past a certain number of results are not generally useful.
      *
      * This checks to see if a particular query is cached if we are trying to sort by modification date.
      * If cached, set a time range filter to minimize results.
      */
     $soField = $query->getSortOrder()->getField();
     if ($prefs['unified_trim_sorted_search'] == 'y') {
         $cacheLib = TikiLib::lib("cache");
         $cacheKey = $query->getExpr()->getSerializedParts();
         // if the sort order is modified or creation date, and there is a trim query cache item,
         // fetch the period filter that it should be filtering by (set in part 2, below) and add it to the search
         if (($soField == "modification_date" || ($soField = "creation_date")) && ($periodFilter = $cacheLib->getCached($cacheKey, "esquery"))) {
             $query->filterRange(strtotime("-" . $periodFilter . " days"), time(), $soField);
         }
     }
     /**End of Sorted Search size adjustment (part 1)*/
     $builder = new Search_Elastic_OrderBuilder();
     $orderPart = $builder->build($query->getSortOrder());
     $builder = new Search_Elastic_FacetBuilder($this->facetCount);
     $facetPart = $builder->build($query->getFacets());
     $builder = new Search_Elastic_RescoreQueryBuilder();
     $rescorePart = $builder->build($query->getExpr());
     $builder = new Search_Elastic_QueryBuilder();
     $builder->setDocumentReader($this->createDocumentReader());
     $queryPart = $builder->build($query->getExpr());
     $postFilterPart = $builder->build($query->getPostFilter()->getExpr());
     if (empty($postFilterPart)) {
         $postFilterPart = [];
     } else {
         $postFilterPart = ["post_filter" => ['fquery' => $postFilterPart]];
     }
     $indices = [$this->index];
     $foreign = array_map(function ($query) use($builder) {
         return $builder->build($query->getExpr());
     }, $query->getForeignQueries());
     foreach ($foreign as $indexName => $foreignQuery) {
         $indices[] = $indexName;
         $queryPart = ['query' => ['indices' => ['index' => $indexName, 'query' => $foreignQuery['query'], 'no_match_query' => $queryPart['query']]]];
     }
     $fullQuery = array_merge($queryPart, $orderPart, $facetPart, $rescorePart, $postFilterPart, array("from" => $resultStart, "size" => $resultCount, "highlight" => array("tags_schema" => "styled", "fields" => array('contents' => array("number_of_fragments" => 5), 'file' => array("number_of_fragments" => 5)))));
     $result = $this->connection->search($indices, $fullQuery);
     $hits = $result->hits;
     /**
      * Sorted Search size adjustment (part 2) - Checks to see if the number of results returned
      * are more than 500. If they are, set an approximate period filter to get to 500 results next
      * time that query is run.
      */
     if ($prefs['unified_trim_sorted_search'] == 'y') {
         if ($hits->total >= 500) {
             if (empty($periodFilter)) {
                 //set the default filter to ~6 months if no filter was previosuly set
                 $periodFilter = 180;
             } else {
                 // estimate the filter required to get 500 results
                 $periodFilter = round(500 / $hits->total * $periodFilter);
             }
             $cacheLib->cacheItem($cacheKey, (string) $periodFilter, "esquery");
         }
         // if total hits was less than 300 and a period filter had been set, increase the period filter
         // for the next search
         if ($hits->total < 300 && !empty($periodFilter)) {
             $periodFilter = round(300 / $hits->total * $periodFilter);
             $cacheLib->cacheItem($cacheKey, (string) $periodFilter, "esquery");
         }
     }
     /** End Sorted Search size adjustment (part 2) */
     $indicesMap = array_combine($indices, $indices);
     $entries = array_map(function ($entry) use(&$indicesMap) {
         $data = (array) $entry->_source;
         if (isset($entry->highlight->contents)) {
             $data['_highlight'] = implode('...', $entry->highlight->contents);
         } elseif (isset($entry->highlight->file)) {
             $data['_highlight'] = implode('...', $entry->highlight->file);
         } else {
             $data['_highlight'] = '';
         }
         $data['score'] = round($entry->_score, 2);
         $index = $entry->_index;
         // Make sure we reduce the returned index to something matching what we requested
         // if what was requested is an alias.
         // Note: This only supports aliases where the name is a prefix.
         if (isset($indicesMap[$index])) {
             $index = $indicesMap[$index];
         } else {
             foreach ($indicesMap as $candidate) {
                 if (0 === strpos($index, $candidate . '_')) {
                     $indicesMap[$index] = $candidate;
                     $index = $candidate;
                     break;
                 }
             }
         }
         $data['_index'] = $index;
         return $data;
     }, $hits->hits);
     $resultSet = new Search_Elastic_ResultSet($entries, $hits->total, $resultStart, $resultCount);
     $reader = new Search_Elastic_FacetReader($result);
     foreach ($query->getFacets() as $facet) {
         if ($filter = $reader->getFacetFilter($facet)) {
             $resultSet->addFacetFilter($filter);
         }
     }
     return $resultSet;
 }