From df55441c4bca508d5326df7158201f7b130a8e63 Mon Sep 17 00:00:00 2001 From: Will Taylor-Jackson Date: Sat, 1 Dec 2018 12:59:06 +0000 Subject: [PATCH 1/5] feat: add date based search functions --- src/QueryBuilder.php | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 05f1aa7..4281400 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -178,6 +178,15 @@ public function whereNestedDoc($column, $query, $boolean = 'and'): self return $this; } + /** + * Add a prefix query + * + * @param string $column + * @param string $value + * @param string $boolean + * @param boolean $not + * @return self + */ public function whereStartsWith($column, string $value, $boolean = 'and', $not = false): self { $type = 'Prefix'; @@ -187,6 +196,105 @@ public function whereStartsWith($column, string $value, $boolean = 'and', $not = return $this; } + /** + * Add a script query + * + * @param string $script + * @param array $options + * @param string $boolean + * @return self + */ + public function whereScript(string $script, array $options = [], $boolean = 'and'): self + { + $type = 'Script'; + + $this->wheres[] = compact('script', 'options', 'type', 'boolean'); + + return $this; + } + + /** + * Add a "where weekday" statement to the query. + * + * @param string $column + * @param string $operator + * @param \DateTimeInterface|string $value + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereWeekday($column, $operator, $value = null, $boolean = 'and') + { + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 + ); + + if ($value instanceof DateTimeInterface) { + $value = $value->format('N'); + } + + return $this->addDateBasedWhere('Weekday', $column, $operator, $value, $boolean); + } + + /** + * Add an "or where weekday" statement to the query. + * + * @param string $column + * @param string $operator + * @param \DateTimeInterface|string $value + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereWeekday($column, $operator, $value = null) + { + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 + ); + + return $this->addDateBasedWhere('Weekday', $column, $operator, $value, 'or'); + } + + /** + * Add a date based (year, month, day, time) statement to the query. + * + * @param string $type + * @param string $column + * @param string $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and') + { + switch ($type) { + case 'Year': + $dateType = 'year'; + break; + + case 'Month': + $dateType = 'monthOfYear'; + break; + + case 'Day': + $dateType = 'dayOfMonth'; + break; + + case 'Weekday': + $dateType = 'dayOfWeek'; + break; + } + + $type = 'Script'; + + $operator = $operator == '=' ? '==' : $operator; + + $script = "doc.{$column}.date.{$dateType} {$operator} params.value"; + + $options['params'] = ['value' => (int) $value]; + + $this->wheres[] = compact('script', 'options', 'type', 'boolean'); + + return $this; + } + /** * Add another query builder as a nested where to the query builder. * From 23739a4d8e3c90b21c752b061a41b733d7210186 Mon Sep 17 00:00:00 2001 From: Will Taylor-Jackson Date: Sat, 1 Dec 2018 13:00:59 +0000 Subject: [PATCH 2/5] fix: add fuzziness to field details if not multi match --- src/QueryGrammar.php | 46 ++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/QueryGrammar.php b/src/QueryGrammar.php index a67a0d0..2d3ef52 100644 --- a/src/QueryGrammar.php +++ b/src/QueryGrammar.php @@ -472,7 +472,7 @@ protected function compileWhereFunctionScore(Builder $builder, array $where): ar } /** - * Compile a where nested geo distance clause + * Compile a search clause * * @param Builder $builder * @param array $where @@ -482,7 +482,7 @@ protected function compileWhereSearch(Builder $builder, array $where): array { $fields = '_all'; - if (!empty($where['options']['fields'])) { + if (! empty($where['options']['fields'])) { $fields = $where['options']['fields']; } @@ -499,24 +499,37 @@ protected function compileWhereSearch(Builder $builder, array $where): array if (is_array($fields) && count($fields) > 1) { $type = isset($where['options']['matchType']) ? $where['options']['matchType'] : 'most_fields'; - $query = array( - 'multi_match' => array( + $query = [ + 'multi_match' => [ 'query' => $where['value'], 'type' => $type, 'fields' => $fields, - ), - ); + ], + ]; } else { - $fields = is_array($fields) ? reset($fields) : $fields; + $field = is_array($fields) ? reset($fields) : $fields; - $query = array( - 'match' => array( - $fields => $where['value'], - ), - ); + $query = [ + 'match' => [ + $field => [ + 'query' => $where['value'], + ] + ], + ]; } - if (!empty($where['options']['constant_score'])) { + if (! empty($where['options']['fuzziness'])) { + $matchType = array_keys($query)[0]; + + if ($matchType === 'multi_match') { + $query[$matchType]['fuzziness'] = $where['options']['fuzziness']; + } + else { + $query[$matchType][$field]['fuzziness'] = $where['options']['fuzziness']; + } + } + + if (! empty($where['options']['constant_score'])) { $query = [ 'constant_score' => [ 'query' => $query, @@ -524,16 +537,11 @@ protected function compileWhereSearch(Builder $builder, array $where): array ]; } - if (!empty($where['options']['fuzziness'])) { - $firstKey = array_keys($query)[0]; - $query[$firstKey]['fuzziness'] = $where['options']['fuzziness']; - } - return $query; } /** - * Compile a where nested geo distance clause + * Compile a geo distance clause * * @param Builder $builder * @param array $where From ff316002ea94ca7b4b7a246b18eaa5139ab4f7ff Mon Sep 17 00:00:00 2001 From: Will Taylor-Jackson Date: Sat, 1 Dec 2018 13:01:12 +0000 Subject: [PATCH 3/5] feat: compile script clause --- src/QueryGrammar.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/QueryGrammar.php b/src/QueryGrammar.php index 2d3ef52..f1272c2 100644 --- a/src/QueryGrammar.php +++ b/src/QueryGrammar.php @@ -540,6 +540,22 @@ protected function compileWhereSearch(Builder $builder, array $where): array return $query; } + /** + * Compile a script clause + * + * @param Builder $builder + * @param array $where + * @return array + */ + protected function compileWhereScript(Builder $builder, array $where): array + { + return [ + 'script' => [ + 'script' => array_merge($where['options'], ['source' => $where['script']]), + ], + ]; + } + /** * Compile a geo distance clause * From 83a4726e1d850e444cebf5a21e744e8d386e5d0f Mon Sep 17 00:00:00 2001 From: Will Taylor-Jackson Date: Sat, 1 Dec 2018 13:02:36 +0000 Subject: [PATCH 4/5] feat: use smaller batch size when scrolling Fixes designmynight/dmn#29691 --- src/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection.php b/src/Connection.php index c60c884..4813ae0 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -200,7 +200,7 @@ public function cursor($query, $bindings = [], $useReadPdo = false) $scrollParams = array( 'scroll' => $scrollTimeout, - 'size' => 500, + 'size' => min(100, $limit), 'index' => $query['index'], 'body' => $query['body'] ); From 9925fe79302b274c714cd80db27504b91895b4f5 Mon Sep 17 00:00:00 2001 From: Will Taylor-Jackson Date: Sat, 1 Dec 2018 13:03:10 +0000 Subject: [PATCH 5/5] fix: only scroll if more results required --- src/Connection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection.php b/src/Connection.php index 4813ae0..5bf7787 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -217,7 +217,7 @@ public function cursor($query, $bindings = [], $useReadPdo = false) yield $result; } - if ( $limit >= $numResults ){ + if ( $limit > $numResults ){ foreach ($this->scroll($scrollId, $scrollTimeout, $limit - $numResults) as $result) { yield $result; }