function testMoreLikeThisQuery() { $builder = new QueryBuilder(); $builder->setDocumentReader(function ($type, $object) { return ['object_type' => $type, 'object_id' => $object, 'contents' => 'hello world']; }); $query = $builder->build(new AndX([new MoreLikeThis('wiki page', 'A')])); $this->assertEquals([], $query['rescore']['query']['rescore_query']['bool']['should']); }
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; }