/** * Process completion search results. * Resolves the titles and rescores. * @param SearchSuggestionSet $suggestions * @return SearchSuggestionSet */ protected function processCompletionResults($search, SearchSuggestionSet $suggestions) { if ($suggestions->getSize() == 0) { // If we don't have anything, don't bother return $suggestions; } $search = trim($search); // preload the titles with LinkBatch $titles = $suggestions->map(function (SearchSuggestion $sugg) { return $sugg->getSuggestedTitle(); }); $lb = new LinkBatch($titles); $lb->setCaller(__METHOD__); $lb->execute(); $results = $suggestions->map(function (SearchSuggestion $sugg) { return $sugg->getSuggestedTitle()->getPrefixedText(); }); // Rescore results with an exact title match $rescorer = new SearchExactMatchRescorer(); $rescoredResults = $rescorer->rescore($search, $this->namespaces, $results, $this->limit); if (count($rescoredResults) > 0) { $found = array_search($rescoredResults[0], $results); if ($found === false) { // If the first result is not in the previous array it // means that we found a new exact match $exactMatch = SearchSuggestion::fromTitle(0, Title::newFromText($rescoredResults[0])); $suggestions->prepend($exactMatch); $suggestions->shrink($this->limit); } else { // if the first result is not the same we need to rescore if ($found > 0) { $suggestions->rescore($found); } } } return $suggestions; }
/** * Process completion search results. * Resolves the titles and rescores. * @param SearchSuggestionSet $suggestions * @return SearchSuggestionSet */ protected function processCompletionResults($search, SearchSuggestionSet $suggestions) { $search = trim($search); // preload the titles with LinkBatch $titles = $suggestions->map(function (SearchSuggestion $sugg) { return $sugg->getSuggestedTitle(); }); $lb = new LinkBatch($titles); $lb->setCaller(__METHOD__); $lb->execute(); $results = $suggestions->map(function (SearchSuggestion $sugg) { return $sugg->getSuggestedTitle()->getPrefixedText(); }); if ($this->offset === 0) { // Rescore results with an exact title match // NOTE: in some cases like cross-namespace redirects // (frequently used as shortcuts e.g. WP:WP on huwiki) some // backends like Cirrus will return no results. We should still // try an exact title match to workaround this limitation $rescorer = new SearchExactMatchRescorer(); $rescoredResults = $rescorer->rescore($search, $this->namespaces, $results, $this->limit); } else { // No need to rescore if offset is not 0 // The exact match must have been returned at position 0 // if it existed. $rescoredResults = $results; } if (count($rescoredResults) > 0) { $found = array_search($rescoredResults[0], $results); if ($found === false) { // If the first result is not in the previous array it // means that we found a new exact match $exactMatch = SearchSuggestion::fromTitle(0, Title::newFromText($rescoredResults[0])); $suggestions->prepend($exactMatch); $suggestions->shrink($this->limit); } else { // if the first result is not the same we need to rescore if ($found > 0) { $suggestions->rescore($found); } } } return $suggestions; }
/** * Builds a new set of suggestion based on a title array. * Useful when using a backend that supports only Titles. * * NOTE: Suggestion scores will be generated. * * @param Title[] $titles * @return SearchSuggestionSet */ public static function fromTitles(array $titles) { $score = count($titles); $suggestions = array_map(function ($title) use(&$score) { return SearchSuggestion::fromTitle($score--, $title); }, $titles); return new SearchSuggestionSet($suggestions); }