Completed
Push — master ( 321c29...f7acb7 )
by Peter
05:07
created

BoostDecorator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 68.97%

Importance

Changes 0
Metric Value
wmc 12
lcom 0
cbo 2
dl 0
loc 76
ccs 20
cts 29
cp 0.6897
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B decorate() 0 34 6
B unify() 0 28 6
1
<?php
2
3
namespace Maslosoft\Manganel\Decorators\QueryBuilder\QueryString;
4
5
use Maslosoft\Manganel\Interfaces\QueryBuilder\QueryStringDecoratorInterface;
6
use Maslosoft\Manganel\Meta\DocumentPropertyMeta;
7
use Maslosoft\Manganel\Meta\ManganelMeta;
8
use Maslosoft\Manganel\SearchCriteria;
9
10
/**
11
 * BoostDecorator
12
 *
13
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
14
 */
15
class BoostDecorator implements QueryStringDecoratorInterface
16
{
17
18 15
	public function decorate(&$queryStringParams, SearchCriteria $criteria)
19
	{
20 15
		$fields = [];
21 15
		$models = $criteria->getModels();
22 15
		foreach ($models as $model)
23
		{
24 15
			$meta = ManganelMeta::create($model);
25 15
			$boosted = $meta->properties('searchBoost');
26
			/* @var $boosted float[] */
27 15
			foreach ($boosted as $name => $boost)
28
			{
29 15
				if ($boost !== 1.0)
30
				{
31 15
					$fields[$name] = $this->unify($name, $boost, $fields);
32
				}
33
			}
34
		}
35
36
		// No custom boost, ignore
37 15
		if (empty($fields))
38
		{
39 13
			return;
40
		}
41 2
		$boosts = [];
42 2
		foreach ($fields as $name => $boost)
43
		{
44 2
			$boosts[] = sprintf('%s^%f', $name, $boost);
45
		}
46
47
		// Add also _all or it would search only boosted fields
48 2
		$boosts[] = '_all';
49
50 2
		$queryStringParams['fields'] = $boosts;
51 2
	}
52
53
	/**
54
	 * Unify boost value if using multi model search with different boost
55
	 * values for field with same name.
56
	 * @param string $field
57
	 * @param float $boost
58
	 * @param float[] $fields
59
	 * @return float
60
	 */
61 2
	private function unify($field, $boost, $fields)
62
	{
63 2
		if (!array_key_exists($field, $fields))
64
		{
65
			// No boost set yet, simply set value
66 2
			return $boost;
67
		}
68
69
		// There are already some boost set, decide whether to use maximum
70
		// or minimum value
71
		$current = $fields[$field];
72
		switch (true)
73
		{
74
			// Choose minimal boost out of all
75
			case $current < 1 && $boost < 1:
76
				$boost = min($current, $boost);
77
				break;
78
			// Choose maximum boost out of all
79
			case $current > 1 && $boost > 1:
80
				$boost = max($current, $boost);
81
				break;
82
			// Choose average, as there is no way to decide whether boost should
83
			// be above one or below
84
			default:
85
				$boost = ($current + $boost) / 2;
86
		}
87
		return $boost;
88
	}
89
90
}
91