Passed
Push — master ( 9975a0...1b82ab )
by Jeroen
02:06
created

SolrEngine::performSearch()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 16
rs 10
cc 3
nc 4
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ScoutEngines\Solr;
6
7
use Illuminate\Database\Eloquent\Collection;
8
use Laravel\Scout\Builder;
9
use Laravel\Scout\Engines\Engine;
10
use Solarium\Client;
11
12
class SolrEngine extends Engine
13
{
14
    /**
15
     * @var Client
16
     */
17
    private $client;
18
19
    /**
20
     * SolrEngine constructor.
21
     *
22
     * @param Client $client
23
     */
24
    public function __construct(Client $client)
25
    {
26
        $this->client = $client;
27
    }
28
29
    /**
30
     * Update the given model in the index.
31
     *
32
     * @param  \Illuminate\Database\Eloquent\Collection $models
33
     * @return void
34
     */
35
    public function update($models)
36
    {
37
        if ($models->isEmpty()) {
38
            return;
39
        }
40
41
        $updateQuery = $this->client->createUpdate();
42
43
        $models->each(function($model) use(&$updateQuery){
44
            $document = $updateQuery->createDocument($model->toSearchableArray());
45
            $updateQuery->addDocument($document);
46
        });
47
48
        $updateQuery->addCommit();
49
50
        $this->client->update($updateQuery);
51
    }
52
53
    /**
54
     * Remove the given model from the index.
55
     *
56
     * @param  \Illuminate\Database\Eloquent\Collection $models
57
     * @return void
58
     */
59
    public function delete($models)
60
    {
61
        if ($models->isEmpty()) {
62
            return;
63
        }
64
65
        $updateQuery = $this->client->createUpdate();
66
67
        $ids = $models->map(function ($model) {
68
            return $model->getScoutKey();
69
        });
70
71
        $updateQuery->addDeleteByIds($ids->toArray());
72
        $updateQuery->addCommit();
73
74
        $this->client->update($updateQuery);
75
    }
76
77
    /**
78
     * Perform the given search on the engine.
79
     *
80
     * @param  \Laravel\Scout\Builder $builder
81
     * @return mixed
82
     */
83
    public function search(Builder $builder)
84
    {
85
        return $this->performSearch($builder);
86
    }
87
88
    /**
89
     * Perform the given search on the engine.
90
     *
91
     * @param  \Laravel\Scout\Builder $builder
92
     * @param  int $perPage
93
     * @param  int $page
94
     * @return mixed
95
     */
96
    public function paginate(Builder $builder, $perPage, $page)
97
    {
98
        return $this->performSearch($builder, $perPage,$page - 1);
99
    }
100
101
    /**
102
     * Pluck and return the primary keys of the given results.
103
     *
104
     * @param  \Solarium\QueryType\Select\Result\Result $results
105
     * @return \Illuminate\Support\Collection
106
     */
107
    public function mapIds($results)
108
    {
109
        $ids = array_map(function ($document) {
110
            return $document->id;
111
        }, $results->getDocuments());
112
113
        return collect($ids);
114
    }
115
116
    /**
117
     * Map the given results to instances of the given model.
118
     *
119
     * @param  \Laravel\Scout\Builder $builder
120
     * @param  \Solarium\QueryType\Select\Result\Result $results
121
     * @param  \Illuminate\Database\Eloquent\Model $model
122
     * @return \Illuminate\Database\Eloquent\Collection
123
     */
124
    public function map(Builder $builder, $results, $model)
125
    {
126
        if (count($results->getDocuments()) === 0) {
127
            return Collection::make();
128
        }
129
130
        $models = $model->getScoutModelsByIds(
131
            $builder, collect($results->getDocuments())->pluck('objectID')->values()->all()
132
        )->keyBy(function ($model) {
133
            return $model->getScoutKey();
134
        });
135
136
        return Collection::make($results['hits'])->map(function ($hit) use ($models) {
137
            if (isset($models[$hit['objectID']])) {
138
                return $models[$hit['objectID']];
139
            }
140
        })->filter()->values();
141
    }
142
143
    /**
144
     * Get the total count from a raw result returned by the engine.
145
     *
146
     * @param  \Solarium\QueryType\Select\Result\Result $results
147
     * @return int
148
     */
149
    public function getTotalCount($results)
150
    {
151
        return $results->getNumFound();
152
    }
153
154
    /**
155
     * Perform the given search on the engine.
156
     *
157
     * @param  \Laravel\Scout\Builder  $builder
158
     * @param  int|null $perPage
159
     * @param  int|null $offset
160
     * @return mixed
161
     */
162
    protected function performSearch(Builder $builder, $perPage = null, $offset = null)
163
    {
164
        $selectQuery = $this->client->createSelect();
165
166
        $conditions = (empty($builder->query)) ? [] : [$builder->query];
167
        $conditions = array_merge($conditions, $this->filters($builder));
168
169
        $selectQuery->setQuery(implode(' ', $conditions));
170
171
        if(!is_null($perPage)) {
172
            $selectQuery->setStart($offset)->setRows($perPage);
173
        }
174
175
        // @todo callback return
176
177
        return $this->client->select($selectQuery);
178
    }
179
180
    /**
181
     * Get the filter array for the query.
182
     *
183
     * @param  \Laravel\Scout\Builder  $builder
184
     * @return array
185
     */
186
    protected function filters(Builder $builder)
187
    {
188
        return collect($builder->wheres)->map(function ($value, $key) {
189
            return sprintf('%s:"%s"', $key, $value);
190
        })->values()->all();
191
    }
192
}