Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
StatementQuantityField
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
3 / 3
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getFieldData
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
 getMapping
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Wikibase\Search\Elastic\Fields;
4
5use CirrusSearch\CirrusSearch;
6use DataValues\UnboundedQuantityValue;
7use SearchEngine;
8use Wikibase\DataModel\Entity\EntityDocument;
9use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
10use Wikibase\DataModel\Statement\Statement;
11use Wikibase\DataModel\Statement\StatementListProvider;
12use 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 */
20class 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}