Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 50 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
WikibaseEntitiesHandler | |
0.00% |
0 / 50 |
|
0.00% |
0 / 3 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
transform | |
0.00% |
0 / 42 |
|
0.00% |
0 / 1 |
306 | |||
getFieldMatch | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace Wikibase\MediaInfo\Search\ASTQueryBuilder; |
4 | |
5 | use CirrusSearch\Parser\AST\ParsedNode; |
6 | use CirrusSearch\Parser\AST\ParsedQuery; |
7 | use Elastica\Query\AbstractQuery; |
8 | use Elastica\Query\BoolQuery; |
9 | use Elastica\Query\DisMax; |
10 | use Elastica\Query\MatchNone; |
11 | use Elastica\Query\MatchQuery; |
12 | use Wikibase\MediaInfo\Search\MediaSearchASTEntitiesExtractor; |
13 | use Wikibase\Search\Elastic\Fields\StatementsField; |
14 | |
15 | class WikibaseEntitiesHandler implements ParsedNodeHandlerInterface { |
16 | /** @var ParsedNode */ |
17 | private $node; |
18 | |
19 | /** @var ParsedQuery */ |
20 | private $query; |
21 | |
22 | /** @var MediaSearchASTEntitiesExtractor */ |
23 | private $entitiesExtractor; |
24 | |
25 | /** @var array */ |
26 | private $boosts; |
27 | |
28 | /** @var bool */ |
29 | private $variableBoost; |
30 | |
31 | public function __construct( |
32 | ParsedNode $node, |
33 | ParsedQuery $query, |
34 | MediaSearchASTEntitiesExtractor $entitiesExtractor, |
35 | array $boosts, |
36 | array $options |
37 | ) { |
38 | $this->node = $node; |
39 | $this->query = $query; |
40 | $this->entitiesExtractor = $entitiesExtractor; |
41 | $this->boosts = $boosts; |
42 | $this->variableBoost = $options['entitiesVariableBoost']; |
43 | } |
44 | |
45 | public function transform(): AbstractQuery { |
46 | $entities = $this->entitiesExtractor->getEntities( $this->query, $this->node ); |
47 | if ( count( $entities ) === 0 ) { |
48 | return new MatchNone(); |
49 | } |
50 | |
51 | $statementsQueries = []; |
52 | $weightedTagsQueries = []; |
53 | |
54 | foreach ( $entities as $entity ) { |
55 | if ( $entity['score'] >= 0 ) { |
56 | foreach ( $this->boosts['statement'] ?? [] as $propertyId => $weight ) { |
57 | $statementBoost = $this->variableBoost ? $weight * $entity['score'] : $weight; |
58 | if ( $statementBoost > 0 ) { |
59 | $statementsQueries[] = $this->getFieldMatch( |
60 | StatementsField::NAME, |
61 | $propertyId . StatementsField::STATEMENT_SEPARATOR . $entity['entityId'], |
62 | $statementBoost |
63 | ); |
64 | } |
65 | } |
66 | } |
67 | |
68 | // ONLY do weighted_tags queries if we have an exact match |
69 | // weighted_tags is a very powerful search signal, so we want to be sure we're |
70 | // searching for the right thing |
71 | if ( $entity['score'] >= 1 ) { |
72 | foreach ( $this->boosts['weighted_tags'] ?? [] as $prefix => $weight ) { |
73 | $weightedTagBoost = $this->variableBoost ? $weight * $entity['score'] : $weight; |
74 | if ( $weightedTagBoost > 0 ) { |
75 | $weightedTagsQueries[] = $this->getFieldMatch( |
76 | 'weighted_tags', |
77 | $prefix . $entity['entityId'], |
78 | $weightedTagBoost |
79 | ); |
80 | } |
81 | } |
82 | } |
83 | } |
84 | |
85 | $statementsQuery = new DisMax(); |
86 | foreach ( $statementsQueries as $query ) { |
87 | $statementsQuery->addQuery( $query ); |
88 | } |
89 | $weightedTagsQuery = new BoolQuery(); |
90 | $weightedTagsQuery->setMinimumShouldMatch( 1 ); |
91 | foreach ( $weightedTagsQueries as $query ) { |
92 | $weightedTagsQuery->addShould( $query ); |
93 | } |
94 | |
95 | if ( count( $statementsQueries ) === 0 && count( $weightedTagsQueries ) === 0 ) { |
96 | return new MatchNone(); |
97 | } |
98 | if ( count( $weightedTagsQueries ) === 0 ) { |
99 | return $statementsQuery; |
100 | } |
101 | if ( count( $statementsQueries ) === 0 ) { |
102 | return $weightedTagsQuery; |
103 | } |
104 | $query = new BoolQuery(); |
105 | $query->setMinimumShouldMatch( 1 ); |
106 | $query->addShould( $statementsQuery ); |
107 | $query->addShould( $weightedTagsQuery ); |
108 | return $query; |
109 | } |
110 | |
111 | private function getFieldMatch( string $field, string $query, float $boost ): MatchQuery { |
112 | return ( new MatchQuery() ) |
113 | ->setFieldQuery( $field, $query ) |
114 | ->setFieldBoost( $field, $boost ); |
115 | } |
116 | } |