Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 43 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
InterwikiSearcher | |
0.00% |
0 / 43 |
|
0.00% |
0 / 3 |
110 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getInterwikiResults | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
72 | |||
getQueryCacheStatsKey | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace CirrusSearch; |
4 | |
5 | use CirrusSearch\Fallbacks\FallbackRunner; |
6 | use CirrusSearch\Parser\BasicQueryClassifier; |
7 | use CirrusSearch\Parser\NamespacePrefixParser; |
8 | use CirrusSearch\Search\CrossProjectBlockScorerFactory; |
9 | use CirrusSearch\Search\FullTextResultsType; |
10 | use CirrusSearch\Search\MSearchRequests; |
11 | use CirrusSearch\Search\SearchContext; |
12 | use CirrusSearch\Search\SearchQuery; |
13 | use CirrusSearch\Search\SearchQueryBuilder; |
14 | use CirrusSearch\Search\TitleHelper; |
15 | use MediaWiki\MediaWikiServices; |
16 | use MediaWiki\Status\Status; |
17 | use MediaWiki\User\User; |
18 | |
19 | /** |
20 | * Performs searches using Elasticsearch -- on interwikis! |
21 | * |
22 | * This program is free software; you can redistribute it and/or modify |
23 | * it under the terms of the GNU General Public License as published by |
24 | * the Free Software Foundation; either version 2 of the License, or |
25 | * (at your option) any later version. |
26 | * |
27 | * This program is distributed in the hope that it will be useful, |
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
30 | * GNU General Public License for more details. |
31 | * |
32 | * You should have received a copy of the GNU General Public License along |
33 | * with this program; if not, write to the Free Software Foundation, Inc., |
34 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
35 | * http://www.gnu.org/copyleft/gpl.html |
36 | */ |
37 | class InterwikiSearcher extends Searcher { |
38 | |
39 | /** |
40 | * @param Connection $connection |
41 | * @param SearchConfig $config |
42 | * @param int[]|null $namespaces Namespace numbers to search, or null for all of them |
43 | * @param User|null $user |
44 | * @param CirrusDebugOptions|null $debugOptions |
45 | * @param NamespacePrefixParser|null $namespacePrefixParser |
46 | * @param InterwikiResolver|null $interwikiResolver |
47 | * @param TitleHelper|null $titleHelper |
48 | * @param CirrusSearchHookRunner|null $cirrusSearchHookRunner |
49 | */ |
50 | public function __construct( |
51 | Connection $connection, |
52 | SearchConfig $config, |
53 | array $namespaces = null, |
54 | User $user = null, |
55 | CirrusDebugOptions $debugOptions = null, |
56 | NamespacePrefixParser $namespacePrefixParser = null, |
57 | InterwikiResolver $interwikiResolver = null, |
58 | TitleHelper $titleHelper = null, |
59 | CirrusSearchHookRunner $cirrusSearchHookRunner = null |
60 | ) { |
61 | $maxResults = $config->get( 'CirrusSearchNumCrossProjectSearchResults' ); |
62 | parent::__construct( $connection, 0, $maxResults, $config, $namespaces, $user, false, |
63 | $debugOptions, $namespacePrefixParser, $interwikiResolver, $titleHelper, $cirrusSearchHookRunner ); |
64 | } |
65 | |
66 | /** |
67 | * Fetch search results, from caches, if there's any |
68 | * @param SearchQuery $query original search query |
69 | * @return Status |
70 | */ |
71 | public function getInterwikiResults( SearchQuery $query ): Status { |
72 | $sources = MediaWikiServices::getInstance() |
73 | ->getService( InterwikiResolver::SERVICE ) |
74 | ->getSisterProjectConfigs(); |
75 | if ( !$sources ) { |
76 | // Nothing to search for |
77 | return Status::newGood( [] ); |
78 | } |
79 | |
80 | $iwQueries = []; |
81 | foreach ( $sources as $interwiki => $config ) { |
82 | $iwQueries[$interwiki] = SearchQueryBuilder::forCrossProjectSearch( $config, $query ) |
83 | ->build(); |
84 | } |
85 | |
86 | $blockScorer = CrossProjectBlockScorerFactory::load( $this->config ); |
87 | $msearches = new MSearchRequests(); |
88 | foreach ( $iwQueries as $interwiki => $iwQuery ) { |
89 | $context = SearchContext::fromSearchQuery( $iwQuery, |
90 | FallbackRunner::create( $iwQuery, $this->interwikiResolver ), $this->cirrusSearchHookRunner ); |
91 | $this->searchContext = $context; |
92 | $this->setResultsType( new FullTextResultsType( |
93 | $this->searchContext->getFetchPhaseBuilder(), |
94 | $query->getParsedQuery()->isQueryOfClass( BasicQueryClassifier::COMPLEX_QUERY ), |
95 | $this->titleHelper, [], $this->searchContext->getConfig()->getElement( 'CirrusSearchDeduplicateInMemory' ) === true ) ); |
96 | $this->config = $context->getConfig(); |
97 | $this->limit = $iwQuery->getLimit(); |
98 | $this->offset = $iwQuery->getOffset(); |
99 | $this->buildFullTextSearch( $query->getParsedQuery()->getQueryWithoutNsHeader() ); |
100 | $this->indexBaseName = $context->getConfig()->get( 'CirrusSearchIndexBaseName' ); |
101 | $search = $this->buildSearch(); |
102 | if ( $this->searchContext->areResultsPossible() ) { |
103 | $msearches->addRequest( $interwiki, $search ); |
104 | } |
105 | } |
106 | |
107 | $searchDescription = "{$this->searchContext->getSearchType()} search for '{$this->searchContext->getOriginalSearchTerm()}'"; |
108 | if ( $this->searchContext->getDebugOptions()->isCirrusDumpQuery() ) { |
109 | return $msearches->dumpQuery( $searchDescription ); |
110 | } |
111 | $mresponses = $this->searchMulti( $msearches ); |
112 | if ( $mresponses->hasFailure() ) { |
113 | return $mresponses->getFailure(); |
114 | } |
115 | |
116 | if ( $this->searchContext->getDebugOptions()->isReturnRaw() ) { |
117 | return $mresponses->dumpResults( $searchDescription ); |
118 | } |
119 | |
120 | return $mresponses->transformAndGetMulti( $this->searchContext->getResultsType(), array_keys( $iwQueries ), |
121 | static function ( array $v ) use ( $blockScorer ) { |
122 | return $blockScorer->reorder( $v ); |
123 | } ); |
124 | } |
125 | |
126 | /** |
127 | * @return string The stats key used for reporting hit/miss rates of the |
128 | * application side query cache. |
129 | */ |
130 | protected function getQueryCacheStatsKey() { |
131 | return 'CirrusSearch.query_cache.interwiki'; |
132 | } |
133 | } |