diff --git a/src/Concerns/BuildsFluentQueries.php b/src/Concerns/BuildsFluentQueries.php index e122abe..b390420 100644 --- a/src/Concerns/BuildsFluentQueries.php +++ b/src/Concerns/BuildsFluentQueries.php @@ -273,6 +273,13 @@ trait BuildsFluentQueries */ protected $source; + /** + * Query returned fields list + * + * @var array|null + */ + protected $fields; + /** * Mapping type * ============ @@ -923,19 +930,27 @@ public function select(...$args): self { $fields = $this->flattenArgs($args); - $this->source[Query::SOURCE_INCLUDES] = array_values(array_unique(array_merge( - $this->source[Query::SOURCE_INCLUDES] ?? [], - $fields - ))); - - $this->source[Query::SOURCE_EXCLUDES] = array_values(array_filter( - $this->source[Query::SOURCE_EXCLUDES] ?? [], function ($field) { - return ! in_array( - $field, + if (Query::$getDataFrom == Query::FIELD_FIELDS) { + $this->fields = array_values(array_unique(array_merge( $this->source[Query::SOURCE_INCLUDES] ?? [], - false - ); - })); + $fields + ))); + } + else { + $this->source[Query::SOURCE_INCLUDES] = array_values(array_unique(array_merge( + $this->source[Query::SOURCE_INCLUDES] ?? [], + $fields + ))); + + $this->source[Query::SOURCE_EXCLUDES] = array_values(array_filter( + $this->source[Query::SOURCE_EXCLUDES] ?? [], function ($field) { + return !in_array( + $field, + $this->source[Query::SOURCE_INCLUDES] ?? [], + false + ); + })); + } return $this; } @@ -1364,6 +1379,16 @@ protected function getBody(): array ); } + if ($this->fields !== null) { + $fields = $body[Query::FIELD_FIELDS] ?? []; + + $body[Query::FIELD_FIELDS] = array_merge( + $fields, + $this->fields + ); + $body[Query::FIELD_SOURCE] = false; + } + $body[self::FIELD_QUERY] = $body[self::FIELD_QUERY] ?? []; if (count($this->must)) { @@ -1512,4 +1537,19 @@ private function resolveRegexpFlags(int $flags): ?string return implode('|', $stringFlags); } + + public function selectFromSource(): self + { + Query::$getDataFrom = Query::FIELD_SOURCE; + + return $this; + } + + public function selectFromFields(): self + { + Query::$getDataFrom = Query::FIELD_FIELDS; + + return $this; + } + } diff --git a/src/Concerns/ExecutesQueries.php b/src/Concerns/ExecutesQueries.php index f2bfc33..1fa7cb7 100644 --- a/src/Concerns/ExecutesQueries.php +++ b/src/Concerns/ExecutesQueries.php @@ -558,9 +558,9 @@ public function update(array $attributes, $id = null): object */ protected function createModelInstance(array $document): Model { - $data = $document[Query::FIELD_SOURCE] ?? []; + $data = $this->flattenValues($document[Query::$getDataFrom] ?? []); $metadata = array_diff_key($document, array_flip([ - Query::FIELD_SOURCE, + Query::$getDataFrom, ])); return $this->getModel()->newInstance( @@ -669,4 +669,32 @@ private function addBaseParams(array $params): array return $params; } + + /** + * ES always returns an array when using "fields" to select columns + * This method turns single element arrays into strings + * + * @param array $params Recieved values + * + * @return array Flattened values + */ + private function flattenValues(array $values): ?array + { + if (Query::$getDataFrom == Query::FIELD_SOURCE) { + return $values; + } + + $flattened = []; + + foreach ($values as $key => $value) { + if (is_array($value) && count($value) == 1) { + $flattened[$key] = $value[0]; + } else { + $flattened[$key] = $value; + } + } + + return $flattened; + } + } diff --git a/src/Query.php b/src/Query.php index 58b4628..d0e29fd 100755 --- a/src/Query.php +++ b/src/Query.php @@ -74,6 +74,8 @@ class Query implements Arrayable, JsonSerializable, Jsonable, IteratorAggregate protected const FIELD_SOURCE = '_source'; + protected const FIELD_FIELDS = 'fields'; + protected const FIELD_TYPE = '_type'; public const GT = self::OPERATOR_GREATER_THAN; @@ -143,6 +145,8 @@ class Query implements Arrayable, JsonSerializable, Jsonable, IteratorAggregate self::SOURCE_EXCLUDES => [], ]; + public static $getDataFrom = self::FIELD_FIELDS; + /** * @var null * @deprecated Use getConnection()->getClient() to access the client instead