Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
32 / 32 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
StatementQuantityField | |
100.00% |
32 / 32 |
|
100.00% |
3 / 3 |
11 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
getFieldData | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
8 | |||
getMapping | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace Wikibase\Search\Elastic\Fields; |
4 | |
5 | use CirrusSearch\CirrusSearch; |
6 | use DataValues\UnboundedQuantityValue; |
7 | use SearchEngine; |
8 | use Wikibase\DataModel\Entity\EntityDocument; |
9 | use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup; |
10 | use Wikibase\DataModel\Statement\Statement; |
11 | use Wikibase\DataModel\Statement\StatementListProvider; |
12 | use Wikibase\Repo\Search\Fields\WikibaseIndexField; |
13 | |
14 | /** |
15 | * Additional field to index statements with their qualifiers and the qualifier value where the |
16 | * qualifier is of type 'quantity' |
17 | * |
18 | * @license GPL-2.0-or-later |
19 | */ |
20 | class StatementQuantityField extends StatementsField implements WikibaseIndexField { |
21 | |
22 | /** |
23 | * Field name |
24 | */ |
25 | public const NAME = 'statement_quantity'; |
26 | |
27 | /** |
28 | * @var array |
29 | */ |
30 | private $allowedQualifierPropertyIds; |
31 | |
32 | /** |
33 | * @param PropertyDataTypeLookup $propertyDataTypeLookup |
34 | * @param string[] $propertyIds List of property IDs to index |
35 | * @param string[] $indexedTypes List of property types to index. Property of this type will be |
36 | * indexed regardless of $propertyIds. |
37 | * @param string[] $excludedIds List of property IDs to exclude. |
38 | * @param callable[] $searchIndexDataFormatters Search formatters, indexed by data type name |
39 | * @param string[] $allowedQualifierPropertyIds Only index if the property id of the statement's |
40 | * qualifier is in this list |
41 | */ |
42 | public function __construct( |
43 | PropertyDataTypeLookup $propertyDataTypeLookup, |
44 | array $propertyIds, |
45 | array $indexedTypes, |
46 | array $excludedIds, |
47 | array $searchIndexDataFormatters, |
48 | array $allowedQualifierPropertyIds |
49 | ) { |
50 | parent::__construct( |
51 | $propertyDataTypeLookup, |
52 | $propertyIds, |
53 | $indexedTypes, |
54 | $excludedIds, |
55 | $searchIndexDataFormatters |
56 | ); |
57 | $this->allowedQualifierPropertyIds = $allowedQualifierPropertyIds; |
58 | } |
59 | |
60 | /** |
61 | * @param EntityDocument $entity |
62 | * |
63 | * @return mixed Get the value of the field to be indexed when a page/document |
64 | * is indexed. This might be an array with nested data, if the field |
65 | * is defined with nested type or an int or string for simple field types. |
66 | */ |
67 | public function getFieldData( EntityDocument $entity ) { |
68 | if ( !( $entity instanceof StatementListProvider ) ) { |
69 | return []; |
70 | } |
71 | |
72 | $data = []; |
73 | |
74 | /** @var Statement $statement */ |
75 | foreach ( $entity->getStatements() as $statement ) { |
76 | $snak = $statement->getMainSnak(); |
77 | $mainSnakString = $this->getWhitelistedSnakAsString( $snak, $statement->getGuid() ); |
78 | if ( $mainSnakString === null ) { |
79 | continue; |
80 | } |
81 | foreach ( $statement->getQualifiers() as $qualifier ) { |
82 | $propertyIdAndValue = $this->getSnakAsPropertyIdAndValue( $qualifier ); |
83 | if ( $propertyIdAndValue !== null && |
84 | $qualifier->getDataValue() instanceof UnboundedQuantityValue && |
85 | in_array( $propertyIdAndValue[ 'propertyId' ], $this->allowedQualifierPropertyIds ) |
86 | ) { |
87 | $data[] = $mainSnakString . '|' . $propertyIdAndValue[ 'value' ]; |
88 | } |
89 | } |
90 | } |
91 | |
92 | return $data; |
93 | } |
94 | |
95 | /** |
96 | * @param SearchEngine $engine |
97 | * |
98 | * @return array |
99 | */ |
100 | public function getMapping( SearchEngine $engine ) { |
101 | // Since we need a specially tuned field, we can not use |
102 | // standard search engine types. |
103 | if ( !( $engine instanceof CirrusSearch ) ) { |
104 | // For now only Cirrus/Elastic is supported |
105 | return []; |
106 | } |
107 | |
108 | //NOTE: needs the cirrus search wikimedia-extra plugin to be installed to work |
109 | $config = [ |
110 | 'type' => 'text', |
111 | 'index_options' => 'freqs', |
112 | 'analyzer' => 'extract_wb_quantity', |
113 | 'search_analyzer' => 'keyword', |
114 | ]; |
115 | |
116 | return $config; |
117 | } |
118 | |
119 | } |