Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.55% |
28 / 29 |
|
75.00% |
3 / 4 |
CRAP | |
0.00% |
0 / 1 |
DescriptionsField | |
96.55% |
28 / 29 |
|
75.00% |
3 / 4 |
11 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getMapping | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
4 | |||
getFieldData | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
getEngineHints | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
2.15 |
1 | <?php |
2 | |
3 | namespace Wikibase\Search\Elastic\Fields; |
4 | |
5 | use CirrusSearch\CirrusSearch; |
6 | use SearchEngine; |
7 | use Wikibase\DataModel\Entity\EntityDocument; |
8 | use Wikibase\DataModel\Term\DescriptionsProvider; |
9 | |
10 | /** |
11 | * Field which contains per-language specific descriptions. |
12 | * |
13 | * @license GPL-2.0-or-later |
14 | * @author Stas Malyshev |
15 | */ |
16 | class DescriptionsField extends TermIndexField { |
17 | |
18 | /** |
19 | * Field name |
20 | */ |
21 | public const NAME = 'descriptions'; |
22 | |
23 | /** |
24 | * List of available languages |
25 | * @var string[] |
26 | */ |
27 | private $languages; |
28 | /** |
29 | * @var array |
30 | */ |
31 | private $stemmingSettings; |
32 | |
33 | /** |
34 | * @param string[] $languages Available languages list. |
35 | * @param array $stemmingSettings Stemming config |
36 | */ |
37 | public function __construct( array $languages, array $stemmingSettings ) { |
38 | $this->languages = $languages; |
39 | parent::__construct( static::NAME, \SearchIndexField::INDEX_TYPE_NESTED ); |
40 | $this->stemmingSettings = $stemmingSettings; |
41 | } |
42 | |
43 | /** |
44 | * @param SearchEngine $engine |
45 | * @return null|array |
46 | */ |
47 | public function getMapping( SearchEngine $engine ) { |
48 | // Since we need a specially tuned field, we can not use |
49 | // standard search engine types. |
50 | if ( !( $engine instanceof CirrusSearch ) ) { |
51 | // For now only Cirrus/Elastic is supported |
52 | return []; |
53 | } |
54 | |
55 | $config = [ |
56 | 'type' => 'object', |
57 | 'properties' => [] |
58 | ]; |
59 | foreach ( $this->languages as $language ) { |
60 | // TODO: here we probably will need better language-specific analyzers |
61 | if ( empty( $this->stemmingSettings[$language]['index'] ) ) { |
62 | $langConfig = $this->getUnindexedField(); |
63 | } else { |
64 | $langConfig = $this->getTokenizedSubfield( $engine->getConfig(), |
65 | $language . '_text', |
66 | $language . '_text_search' |
67 | ); |
68 | } |
69 | $langConfig['fields']['plain'] = $this->getTokenizedSubfield( $engine->getConfig(), $language . '_plain', |
70 | $language . '_plain_search' ); |
71 | $config['properties'][$language] = $langConfig; |
72 | } |
73 | |
74 | return $config; |
75 | } |
76 | |
77 | /** |
78 | * @param EntityDocument $entity |
79 | * |
80 | * @return array|null Array of descriptions in available languages. |
81 | */ |
82 | public function getFieldData( EntityDocument $entity ) { |
83 | if ( !( $entity instanceof DescriptionsProvider ) ) { |
84 | return null; |
85 | } |
86 | $data = []; |
87 | foreach ( $entity->getDescriptions() as $language => $desc ) { |
88 | // While wikibase can only have a single description, |
89 | // WikibaseMediaInfo reports an array of descriptions. To keep the |
90 | // constructed search docs consistent report an array here as well. |
91 | $data[$language] = [ $desc->getText() ]; |
92 | } |
93 | // Shouldn't return empty arrays, that will be encoded to json as an |
94 | // empty list instead of an empty map. Elastic doesn't mind, but this |
95 | // allows more consistency working with the resulting cirrus docs |
96 | return $data ?: null; |
97 | } |
98 | |
99 | /** |
100 | * Set engine hints. |
101 | * Specifically, sets noop hint so that descriptions would be compared |
102 | * as arrays and removal of description would be processed correctly. |
103 | * @param SearchEngine $engine |
104 | * @return array |
105 | */ |
106 | public function getEngineHints( SearchEngine $engine ) { |
107 | if ( !( $engine instanceof CirrusSearch ) ) { |
108 | // For now only Cirrus/Elastic is supported |
109 | return []; |
110 | } |
111 | return [ \CirrusSearch\Search\CirrusIndexField::NOOP_HINT => "equals" ]; |
112 | } |
113 | |
114 | } |