Skip to content

Commit e79fd0b

Browse files
committed
Merge remote-tracking branch 'origin/dev' into dev-l8
2 parents 9ccce9c + 2c7c599 commit e79fd0b

File tree

5 files changed

+287
-28
lines changed

5 files changed

+287
-28
lines changed

src/DSL/Bridge.php

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ public function processDistinct($wheres, $options, $columns, $includeDocCount =
143143
unset($options['skip']);
144144
unset($options['limit']);
145145

146+
if ($sort) {
147+
$sortField = key($sort);
148+
$sortDir = $sort[$sortField]['order'] ?? 'asc';
149+
$sort = [$sortField => $sortDir];
150+
}
151+
152+
146153
$params = $this->buildParams($this->index, $wheres, $options);
147154
$params['body']['aggs'] = $this->createNestedAggs($columns, $sort);
148155

@@ -827,6 +834,7 @@ private function _sanitizeSearchResponse($response, $params, $queryTag)
827834
$meta['timed_out'] = $response['timed_out'];
828835
$meta['total'] = $response['hits']['total']['value'] ?? 0;
829836
$meta['max_score'] = $response['hits']['max_score'] ?? 0;
837+
$meta['sorts'] = [];
830838
$data = [];
831839
if (!empty($response['hits']['hits'])) {
832840
foreach ($response['hits']['hits'] as $hit) {
@@ -838,13 +846,55 @@ private function _sanitizeSearchResponse($response, $params, $queryTag)
838846
$datum[$key] = $value;
839847
}
840848
}
841-
$data[] = $datum;
849+
if (!empty($hit['inner_hits'])) {
850+
foreach ($hit['inner_hits'] as $innerKey => $innerHit) {
851+
$datum[$innerKey] = $this->_filterInnerHits($innerHit);
852+
}
853+
}
854+
855+
//------------------------ later, maybe ------------------------------
856+
// if (!empty($hit['sort'])) {
857+
// $datum['_meta']['sort'] = $this->_parseSort($hit['sort'], $params['body']['sort'] ?? []);
858+
// }
859+
//----------------------------------------------------------------------
860+
861+
862+
{
863+
$data[] = $datum;
864+
}
842865
}
843866
}
844867

845868
return $this->_return($data, $meta, $params, $queryTag);
846869
}
847870

871+
private function _filterInnerHits($innerHit)
872+
{
873+
$hits = [];
874+
foreach ($innerHit['hits']['hits'] as $inner) {
875+
$innerDatum = [];
876+
if (!empty($inner['_source'])) {
877+
foreach ($inner['_source'] as $innerSourceKey => $innerSourceValue) {
878+
$innerDatum[$innerSourceKey] = $innerSourceValue;
879+
}
880+
}
881+
$hits[] = $innerDatum;
882+
}
883+
884+
return $hits;
885+
}
886+
887+
888+
private function _parseSort($sort, $sortParams)
889+
{
890+
$sortValues = [];
891+
foreach ($sort as $key => $value) {
892+
$sortValues[array_key_first($sortParams[$key])] = $value;
893+
}
894+
895+
return $sortValues;
896+
}
897+
848898
private function _sanitizeDistinctResponse($response, $columns, $includeDocCount)
849899
{
850900
$keys = [];

src/DSL/ParameterBuilder.php

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,63 @@ public static function query($dsl): array
3333
}
3434

3535

36-
public static function fieldSort($field, $order = 'asc'): array
36+
public static function fieldSort($field, $payload): array
3737
{
38+
if (!empty($payload['is_geo'])) {
39+
return self::fieldSortGeo($field, $payload);
40+
}
41+
if (!empty($payload['is_nested'])) {
42+
return self::filterNested($field, $payload);
43+
}
44+
$sort = [];
45+
$sort['order'] = $payload['order'] ?? 'asc';
46+
if (!empty($payload['mode'])) {
47+
$sort['mode'] = $payload['mode'];
48+
}
49+
if (!empty($payload['missing'])) {
50+
$sort['missing'] = $payload['missing'];
51+
}
52+
3853
return [
39-
$field => [
40-
'order' => $order,
41-
],
54+
$field => $sort,
55+
];
56+
}
57+
58+
public static function fieldSortGeo($field, $payload): array
59+
{
60+
$sort = [];
61+
$sort[$field] = $payload['pin'];
62+
$sort['order'] = $payload['order'] ?? 'asc';
63+
$sort['unit'] = $payload['unit'] ?? 'km';
64+
65+
if (!empty($payload['mode'])) {
66+
$sort['mode'] = $payload['mode'];
67+
}
68+
if (!empty($payload['type'])) {
69+
$sort['distance_type'] = $payload['type'];
70+
}
71+
72+
return [
73+
'_geo_distance' => $sort,
74+
];
75+
}
76+
77+
public static function filterNested($field, $payload)
78+
{
79+
$sort = [];
80+
$pathParts = explode('.', $field);
81+
$path = $pathParts[0];
82+
$sort['order'] = $payload['order'] ?? 'asc';
83+
if (!empty($payload['mode'])) {
84+
$sort['mode'] = $payload['mode'];
85+
}
86+
$sort['nested'] = [
87+
'path' => $path,
88+
];
89+
90+
91+
return [
92+
$field => $sort,
4293
];
4394
}
4495

src/DSL/QueryBuilder.php

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,14 @@ public function createNestedAggs($columns, $sort)
129129
if (!isset($terms['terms']['order'])) {
130130
$terms['terms']['order'] = [];
131131
}
132-
if ($sort['_count'] == 1) {
132+
if ($sort['_count'] == 'asc') {
133133
$terms['terms']['order'][] = ['_count' => 'asc'];
134134
} else {
135135
$terms['terms']['order'][] = ['_count' => 'desc'];
136136
}
137137
}
138138
if (isset($sort[$columns[0]])) {
139-
if ($sort[$columns[0]] == 1) {
139+
if ($sort[$columns[0]] == 'asc') {
140140
$terms['terms']['order'][] = ['_key' => 'asc'];
141141
} else {
142142
$terms['terms']['order'][] = ['_key' => 'desc'];
@@ -205,15 +205,15 @@ private function _buildQuery($wheres): array
205205
}
206206

207207

208-
public function _convertWheresToDSL($wheres): array
208+
public function _convertWheresToDSL($wheres, $parentField = false): array
209209
{
210210
$dsl = ['bool' => []];
211211
foreach ($wheres as $logicalOperator => $conditions) {
212212
switch ($logicalOperator) {
213213
case 'and':
214214
$dsl['bool']['must'] = [];
215215
foreach ($conditions as $condition) {
216-
$parsedCondition = $this->_parseCondition($condition);
216+
$parsedCondition = $this->_parseCondition($condition, $parentField);
217217
if (!empty($parsedCondition)) {
218218
$dsl['bool']['must'][] = $parsedCondition;
219219
}
@@ -225,7 +225,7 @@ public function _convertWheresToDSL($wheres): array
225225
$boolClause = ['bool' => ['must' => []]];
226226
foreach ($conditionGroup as $subConditions) {
227227
foreach ($subConditions as $subCondition) {
228-
$parsedCondition = $this->_parseCondition($subCondition);
228+
$parsedCondition = $this->_parseCondition($subCondition, $parentField);
229229
if (!empty($parsedCondition)) {
230230
$boolClause['bool']['must'][] = $parsedCondition;
231231
}
@@ -237,17 +237,22 @@ public function _convertWheresToDSL($wheres): array
237237
}
238238
break;
239239
default:
240-
return $this->_parseCondition($wheres);
240+
return $this->_parseCondition($wheres, $parentField);
241241
}
242242
}
243243

244244
return $dsl;
245245
}
246246

247-
private function _parseCondition($condition): array
247+
private function _parseCondition($condition, $parentField = null): array
248248
{
249-
// dd($condition);
250249
$field = key($condition);
250+
if ($parentField) {
251+
if (!str_starts_with($field, $parentField.'.')) {
252+
$field = $parentField.'.'.$field;
253+
}
254+
}
255+
251256
$value = current($condition);
252257

253258

@@ -345,7 +350,7 @@ private function _parseCondition($condition): array
345350
$queryPart = [
346351
'nested' => [
347352
'path' => $field,
348-
'query' => $this->_convertWheresToDSL($operand['wheres']),
353+
'query' => $this->_convertWheresToDSL($operand['wheres'], $field),
349354
'score_mode' => $operand['score_mode'],
350355
],
351356
];
@@ -365,6 +370,21 @@ private function _parseCondition($condition): array
365370
],
366371

367372
];
373+
break;
374+
case 'innerNested':
375+
$options = $this->_buildNestedOptions($operand['options'], $field);
376+
$query = ParameterBuilder::matchAll()['query'];
377+
if (!empty($operand['wheres'])) {
378+
$query = $this->_convertWheresToDSL($operand['wheres'], $field);
379+
}
380+
$queryPart = [
381+
'nested' => [
382+
'path' => $field,
383+
'query' => $query,
384+
'inner_hits' => $options,
385+
],
386+
];
387+
368388
break;
369389
default:
370390
abort('400', 'Invalid operator ['.$operator.'] provided for condition.');
@@ -390,8 +410,8 @@ private function _buildOptions($options): array
390410
if (!isset($return['body']['sort'])) {
391411
$return['body']['sort'] = [];
392412
}
393-
foreach ($value as $field => $direction) {
394-
$return['body']['sort'][] = $this->_parseSortOrder($field, $direction);
413+
foreach ($value as $field => $sortPayload) {
414+
$return['body']['sort'][] = ParameterBuilder::fieldSort($field, $sortPayload);
395415
}
396416
break;
397417
case 'skip':
@@ -405,8 +425,10 @@ private function _buildOptions($options): array
405425
$this->_parseFilter($filterType, $filerValues);
406426
}
407427
break;
428+
408429
case 'multiple':
409430
case 'searchOptions':
431+
410432
//Pass through
411433
break;
412434
default:
@@ -418,6 +440,32 @@ private function _buildOptions($options): array
418440
return $return;
419441
}
420442

443+
private function _buildNestedOptions($options, $field)
444+
{
445+
$options = $this->_buildOptions($options);
446+
if (!empty($options['body'])) {
447+
$body = $options['body'];
448+
unset($options['body']);
449+
$options = array_merge($options, $body);
450+
}
451+
if (!empty($options['sort'])) {
452+
//ensure that the sort field is prefixed with the nested field
453+
$sorts = [];
454+
foreach ($options['sort'] as $sort) {
455+
foreach ($sort as $sortField => $sortPayload) {
456+
if (!str_starts_with($sortField, $field.'.')) {
457+
$sortField = $field.'.'.$sortField;
458+
}
459+
$sorts[] = [$sortField => $sortPayload];
460+
}
461+
}
462+
463+
$options['sort'] = $sorts;
464+
}
465+
466+
return $options;
467+
}
468+
421469
public function _parseFilter($filterType, $filterPayload): void
422470
{
423471
switch ($filterType) {
@@ -440,15 +488,6 @@ public function _parseFilter($filterType, $filterPayload): void
440488
}
441489
}
442490

443-
private function _parseSortOrder($field, $direction): array
444-
{
445-
$dir = 'desc';
446-
if ($direction == 1) {
447-
$dir = 'asc';
448-
}
449-
450-
return ParameterBuilder::fieldSort($field, $dir);
451-
}
452491

453492
public function _parseFilterParameter($params, $filer)
454493
{

src/Eloquent/Docs/ModelDocs.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
* @method $this whereNotNestedObject(string $column, Callable $callback, string $scoreType = 'avg')
3030
* @method $this firstOrCreate(array $attributes, array $values = [])
3131
* @method $this firstOrCreateWithoutRefresh(array $attributes, array $values = [])
32+
* @method $this orderBy(string $column, string $direction = 'asc', string $mode = null, array $missing = '_last')
33+
* @method $this orderByDesc(string $column, string $mode = null, array $missing = '_last')
34+
* @method $this orderByGeo(string $column, array $pin, $direction = 'asc', $unit = 'km', $mode = null, $type = 'arc')
35+
* @method $this orderByGeoDesc(string $column, array $pin, $unit = 'km', $mode = null, $type = 'arc')
36+
* @method $this orderByNested(string $column, string $direction = 'asc', string $mode = null)
37+
*
38+
* @method $this queryNested(string $column, Callable $callback)
39+
*
3240
* @method $this deleteIndexIfExists()
3341
*
3442
*

0 commit comments

Comments
 (0)