Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 33 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
Searcher | |
0.00% |
0 / 33 |
|
0.00% |
0 / 4 |
56 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
performSearch | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
20 | |||
newLog | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
getRelevanceRescoreConfigurations | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace GeoData; |
4 | |
5 | use CirrusSearch\ElasticsearchIntermediary; |
6 | use CirrusSearch\Search\SearchContext; |
7 | use CirrusSearch\SearchConfig; |
8 | use CirrusSearch\SearchRequestLog; |
9 | use ConfigException; |
10 | use Elastica\Exception\ExceptionInterface; |
11 | use Elastica\Exception\ResponseException; |
12 | use Elastica\Search; |
13 | use MediaWiki\MediaWikiServices; |
14 | use MediaWiki\User\UserIdentity; |
15 | use MediaWiki\WikiMap\WikiMap; |
16 | use StatusValue; |
17 | |
18 | /** |
19 | * Performs ES searches via CirrusSearch infrastructure |
20 | */ |
21 | class Searcher extends ElasticsearchIntermediary { |
22 | |
23 | /** @var SearchConfig */ |
24 | private $config; |
25 | |
26 | /** |
27 | * @param UserIdentity|null $user |
28 | * @throws ConfigException |
29 | */ |
30 | public function __construct( UserIdentity $user = null ) { |
31 | /** @var SearchConfig $config */ |
32 | $config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'CirrusSearch' ); |
33 | '@phan-var SearchConfig $config'; |
34 | $this->config = $config; |
35 | $connection = new \CirrusSearch\Connection( $config ); |
36 | |
37 | parent::__construct( $connection, $user, 0 ); |
38 | } |
39 | |
40 | /** |
41 | * Perform search |
42 | * |
43 | * @param \Elastica\Query $query |
44 | * @param int[] $namespaces Namespaces used |
45 | * @param string $queryType Query description for logging |
46 | * @return \StatusValue Holds a \Elastica\ResultSet |
47 | * @throws ExceptionInterface |
48 | */ |
49 | public function performSearch( \Elastica\Query $query, array $namespaces, string $queryType ): StatusValue { |
50 | $indexSuffix = $this->connection->pickIndexSuffixForNamespaces( $namespaces ); |
51 | $index = $this->connection->getIndex( WikiMap::getCurrentWikiId(), $indexSuffix ); |
52 | $search = $index->createSearch( $query ); |
53 | |
54 | $this->connection->setTimeout( $this->getClientTimeout( $queryType ) ); |
55 | $search->setOption( Search::OPTION_TIMEOUT, $this->getTimeout( $queryType ) ); |
56 | |
57 | try { |
58 | $log = $this->newLog( 'performing {queryType}', $queryType, [], $namespaces ); |
59 | $this->start( $log ); |
60 | $result = $search->search(); |
61 | if ( !$result->getResponse()->isOk() ) { |
62 | $req = $this->connection->getClient()->getLastRequest(); |
63 | // Not really the right exception, this is probably a status code problem. |
64 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullable |
65 | throw new ResponseException( $req, $result->getResponse() ); |
66 | } |
67 | $this->success(); |
68 | } catch ( ExceptionInterface $ex ) { |
69 | return $this->failure( $ex ); |
70 | } |
71 | |
72 | $status = StatusValue::newGood( $result ); |
73 | if ( $result->getResponse()->getData()['timed_out'] ?? false ) { |
74 | // only partial results returned |
75 | $status->warning( 'geodata-search-timeout' ); |
76 | } |
77 | return $status; |
78 | } |
79 | |
80 | /** |
81 | * @param string $description |
82 | * @param string $queryType |
83 | * @param string[] $extra |
84 | * @param array|null $namespaces |
85 | * @return SearchRequestLog |
86 | */ |
87 | protected function newLog( |
88 | $description, |
89 | $queryType, |
90 | array $extra = [], |
91 | array $namespaces = null |
92 | ): SearchRequestLog { |
93 | return new SearchRequestLog( |
94 | $this->connection->getClient(), |
95 | $description, |
96 | $queryType, |
97 | $extra, |
98 | $namespaces |
99 | ); |
100 | } |
101 | |
102 | /** |
103 | * @param int[] $namespaces |
104 | * @return array[] Rescore configurations as used by elasticsearch. |
105 | */ |
106 | public function getRelevanceRescoreConfigurations( array $namespaces ): array { |
107 | $searchContext = new SearchContext( $this->config, $namespaces ); |
108 | return $searchContext->getRescore(); |
109 | } |
110 | } |