Skip to content

Commit efe02c5

Browse files
committed
Full index searching, geo & regex queries for Laravel 7
1 parent 3ebafba commit efe02c5

File tree

6 files changed

+599
-42
lines changed

6 files changed

+599
-42
lines changed

src/DSL/Bridge.php

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,14 @@
44

55
use Exception;
66
use Elasticsearch\Client;
7-
use Illuminate\Support\Carbon;
87
use ONGR\ElasticsearchDSL\Aggregation\Matrix\MaxAggregation as MatrixAggregation;
98
use ONGR\ElasticsearchDSL\Aggregation\Metric\AvgAggregation;
109
use ONGR\ElasticsearchDSL\Aggregation\Metric\MaxAggregation;
1110
use ONGR\ElasticsearchDSL\Aggregation\Metric\MinAggregation;
1211
use ONGR\ElasticsearchDSL\Aggregation\Metric\SumAggregation;
13-
use ONGR\ElasticsearchDSL\Query\FullText\QueryStringQuery;
14-
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
1512
use ONGR\ElasticsearchDSL\Query\TermLevel\IdsQuery;
1613
use ONGR\ElasticsearchDSL\Search;
17-
use ONGR\ElasticsearchDSL\Sort\FieldSort;
14+
1815

1916
class Bridge
2017
{
@@ -32,7 +29,6 @@ class Bridge
3229
private $index;
3330

3431

35-
3632
public function __construct(Client $client, $index, $maxSize)
3733
{
3834
$this->client = $client;
@@ -123,23 +119,32 @@ public function processFind($wheres, $options, $columns): Results
123119
// }
124120
// }
125121
$params = $this->buildParams($this->index, $wheres, $options, $columns);
122+
123+
return $this->_returnSearch($params, __FUNCTION__);
124+
125+
}
126+
127+
public function processSearch($searchParams, $searchOptions, $wheres, $opts, $fields, $cols)
128+
{
129+
$params = $this->buildSearchParams($this->index, $searchParams, $searchOptions, $wheres, $opts, $fields, $cols);
130+
131+
return $this->_returnSearch($params, __FUNCTION__);
132+
133+
}
134+
135+
protected function _returnSearch($params, $source)
136+
{
126137
if (empty($params['size'])) {
127138
$params['size'] = $this->maxSize;
128139
}
129140
try {
130141
$process = $this->client->search($params);
131142

132-
return $this->_sanitizeSearchResponse($process, $params, $this->_queryTag(__FUNCTION__));
143+
return $this->_sanitizeSearchResponse($process, $params, $this->_queryTag($source));
133144
} catch (Exception $e) {
134145

135-
return $this->_returnError($e->getMessage(), $e->getCode(), $params, $this->_queryTag(__FUNCTION__));
146+
return $this->_returnError($e->getMessage(), $e->getCode(), $params, $this->_queryTag($source));
136147
}
137-
138-
}
139-
140-
public function processSearch($term, $options, $columns = [])
141-
{
142-
// $params = $this->_buildParams([], $options);
143148
}
144149

145150
public function processDistinct($column, $wheres): Results
@@ -148,7 +153,7 @@ public function processDistinct($column, $wheres): Results
148153
if (is_array($column)) {
149154
$col = $column[0];
150155
}
151-
$params = $this->buildParams($this->index,$wheres);
156+
$params = $this->buildParams($this->index, $wheres);
152157
$params['body']['aggs']['distinct_'.$col]['terms'] = [
153158
'field' => $col,
154159
'size' => $this->maxSize,
@@ -174,7 +179,7 @@ public function processDistinct($column, $wheres): Results
174179

175180
public function processShowQuery($wheres, $options, $columns)
176181
{
177-
$params = $this->buildParams($this->index,$wheres, $options, $columns);
182+
$params = $this->buildParams($this->index, $wheres, $options, $columns);
178183

179184
return $params['body']['query']['query_string']['query'] ?? null;
180185
}
@@ -217,8 +222,6 @@ public function processSave($data, $refresh): Results
217222

218223
}
219224

220-
221-
222225
public function processInsertOne($values, $refresh): Results
223226
{
224227
return $this->processSave($values, $refresh);
@@ -550,7 +553,7 @@ private function _minAggregate($wheres, $options, $columns): Results
550553

551554
private function _sumAggregate($wheres, $options, $columns): Results
552555
{
553-
$params = $this->buildParams($this->index,$wheres, $options);
556+
$params = $this->buildParams($this->index, $wheres, $options);
554557
try {
555558
$agg = new SumAggregation('sum_value', $columns[0]);
556559
$params['body']['aggs']['sum_value'] = $agg->toArray();
@@ -582,7 +585,7 @@ private function _avgAggregate($wheres, $options, $columns): Results
582585

583586
private function _matrixAggregate($wheres, $options, $columns): Results
584587
{
585-
$params = $this->buildParams($this->index,$wheres, $options);
588+
$params = $this->buildParams($this->index, $wheres, $options);
586589
try {
587590
$agg = new MatrixAggregation('sum_value', $columns);
588591
$params['body']['aggs']['statistics'] = $agg->toArray();
@@ -602,7 +605,6 @@ private function _matrixAggregate($wheres, $options, $columns): Results
602605
//======================================================================
603606

604607

605-
606608
private function _queryTag($function)
607609
{
608610
return str_replace('process', '', $function);

src/DSL/QueryBuilder.php

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,81 @@
1212
trait QueryBuilder
1313
{
1414

15+
public static $filter;
16+
1517
protected static $bucketOperators = ['and', 'or'];
1618

1719
protected static $equivalenceOperators = ['in', 'nin'];
1820

19-
protected static $clauseOperators = ['ne', 'gt', 'gte', 'lt', 'lte', 'between', 'not_between', 'like', 'not_like', 'exists'];
21+
protected static $clauseOperators = ['ne', 'gt', 'gte', 'lt', 'lte', 'between', 'not_between', 'like', 'not_like', 'exists', 'regex'];
22+
23+
24+
//======================================================================
25+
// Parameter builders
26+
//======================================================================
27+
28+
public static function buildSearchParams($index, $searchQuery, $searchOptions, $wheres = [], $options = [], $fields = [], $columns = [])
29+
{
30+
$params = [];
31+
if ($index) {
32+
$params['index'] = $index;
33+
}
34+
$params['body'] = [];
35+
36+
37+
$queryString['query'] = $searchQuery;
38+
if ($wheres) {
39+
$wheres = self::_buildQuery($wheres);
40+
$whereQueryString = $wheres['query']['query_string']['query'] ?? null;
41+
if ($whereQueryString) {
42+
$queryString['query'] = '('.$searchQuery.') AND '.$whereQueryString;
43+
}
44+
}
45+
46+
if ($fields) {
47+
$queryString['fields'] = [];
48+
foreach ($fields as $field => $boostLevel) {
49+
if ($boostLevel > 1) {
50+
$field = $field.'^'.$boostLevel;
51+
}
52+
$queryString['fields'][] = $field;
53+
}
54+
}
55+
if ($searchOptions) {
56+
foreach ($searchOptions as $searchOption => $searchOptionValue) {
57+
$queryString[$searchOption] = $searchOptionValue;
58+
}
59+
}
60+
61+
$params['body']['query']['query_string'] = $queryString;
62+
63+
if ($columns && $columns != '*') {
64+
$params['body']['_source'] = $columns;
65+
}
66+
if ($options) {
67+
$opts = self::_buildOptions($options);
68+
if ($opts) {
69+
foreach ($opts as $key => $value) {
70+
if (isset($params[$key])) {
71+
$params[$key] = array_merge($params[$key], $opts[$key]);
72+
} else {
73+
$params[$key] = $value;
74+
}
75+
}
76+
}
77+
}
78+
if (self::$filter) {
79+
$params = self::_parseFilterParameter($params, self::$filter);
80+
}
81+
82+
return $params;
83+
}
2084

2185
public static function buildParams($index, $wheres, $options = [], $columns = [], $_id = null)
2286
{
23-
if ($index){
87+
if ($index) {
2488
$params = [
25-
'index' => $index
89+
'index' => $index,
2690
];
2791
}
2892

@@ -45,10 +109,17 @@ public static function buildParams($index, $wheres, $options = [], $columns = []
45109
}
46110
}
47111
}
112+
if (self::$filter) {
113+
$params = self::_parseFilterParameter($params, self::$filter);
114+
}
48115

49116
return $params;
50117
}
51118

119+
//----------------------------------------------------------------------
120+
// Parsers
121+
//----------------------------------------------------------------------
122+
52123
private static function _buildQueryString($wheres): string
53124
{
54125
if ($wheres) {
@@ -141,6 +212,8 @@ private static function _parseParams($key, $value): string
141212
return '('.$key.':*'.self::_escape($opVal).'*)';
142213
case 'not_like':
143214
return '(NOT '.$key.':*'.self::_escape($opVal).'*)';
215+
case 'regex':
216+
return '('.$key.':/'.$opVal.'/)';
144217
case 'exists':
145218
if ($opVal) {
146219
return '(_exists_:'.$key.')';
@@ -173,7 +246,7 @@ private static function _parseParams($key, $value): string
173246

174247
}
175248

176-
private static function _escape($string): string
249+
public static function _escape($string): string
177250
{
178251
//+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
179252
$stripped = preg_replace('/\W/', '\\\\$0', $string);
@@ -225,7 +298,17 @@ private static function _buildOptions($options): array
225298
case 'skip':
226299
$return['from'] = $value;
227300
break;
301+
case 'minScore':
302+
$return['body']['min_score'] = $value;
303+
break;
304+
case 'filters':
305+
foreach ($value as $filterType => $filerValues) {
306+
self::_parseFilter($filterType, $filerValues);
307+
}
308+
break;
228309
case 'multiple':
310+
case 'searchOptions':
311+
//Pass through
229312
break;
230313
default:
231314
throw new Exception('Unexpected option: '.$key);
@@ -236,6 +319,28 @@ private static function _buildOptions($options): array
236319
return $return;
237320
}
238321

322+
public static function _parseFilter($filterType, $filterPayload)
323+
{
324+
switch ($filterType) {
325+
case 'filterGeoBox':
326+
self::$filter['filter']['geo_bounding_box'][$filterPayload['field']] = [
327+
'top_left' => $filterPayload['topLeft'],
328+
'bottom_right' => $filterPayload['bottomRight'],
329+
];
330+
break;
331+
case 'filterGeoPoint':
332+
self::$filter['filter']['geo_distance'] = [
333+
'distance' => $filterPayload['distance'],
334+
$filterPayload['field'] => [
335+
'lat' => $filterPayload['geoPoint'][0],
336+
'lon' => $filterPayload['geoPoint'][1],
337+
],
338+
339+
];
340+
break;
341+
}
342+
}
343+
239344
private static function _parseSortOrder($value): array
240345
{
241346
$field = array_key_first($value);
@@ -249,4 +354,37 @@ private static function _parseSortOrder($value): array
249354

250355
return $sort->toArray();
251356
}
357+
358+
public static function _parseFilterParameter($params, $filer)
359+
{
360+
$body = $params['body'];
361+
if (!empty($body['query']['match_all'])) {
362+
$filteredBody = [
363+
'query' => [
364+
'bool' => [
365+
'must' => [
366+
'match_all' => $body['query']['match_all'],
367+
],
368+
'filter' => $filer['filter'],
369+
],
370+
],
371+
];
372+
$params['body'] = $filteredBody;
373+
}
374+
if (!empty($body['query']['query_string'])) {
375+
$filteredBody = [
376+
'query' => [
377+
'bool' => [
378+
'must' => [
379+
'query_string' => $body['query']['query_string'],
380+
],
381+
'filter' => $filer['filter'],
382+
],
383+
],
384+
];
385+
$params['body'] = $filteredBody;
386+
}
387+
388+
return $params;
389+
}
252390
}

0 commit comments

Comments
 (0)