connectionManager = $connectionManager; $this->fieldMapper = $fieldMapper; $this->clientConfig = $clientConfig; $this->fieldName = $fieldName; $this->storeId = $storeId; $this->entityIds = $entityIds; $this->searchIndexNameResolver = $searchIndexNameResolver; } /** * {@inheritdoc} */ public function load($limit, $offset = null, $lower = null, $upper = null) { $from = $to = []; if ($lower) { $from = ['gte' => $lower - self::DELTA]; } if ($upper) { $to = ['lt' => $upper - self::DELTA]; } $requestQuery = $this->prepareBaseRequestQuery($from, $to); $requestQuery = array_merge_recursive( $requestQuery, ['body' => ['stored_fields' => [$this->fieldName], 'size' => $limit]] ); if ($offset) { $requestQuery['body']['from'] = $offset; } $queryResult = $this->connectionManager->getConnection() ->query($requestQuery); return $this->arrayValuesToFloat($queryResult['hits']['hits'], $this->fieldName); } /** * {@inheritdoc} */ public function loadPrevious($data, $index, $lower = null) { if ($lower) { $from = ['gte' => $lower - self::DELTA]; } if ($data) { $to = ['lt' => $data - self::DELTA]; } $requestQuery = $this->prepareBaseRequestQuery($from, $to); $requestQuery = array_merge_recursive( $requestQuery, ['size' => 0] ); $queryResult = $this->connectionManager->getConnection() ->query($requestQuery); $offset = $queryResult['hits']['total']; if (!$offset) { return false; } return $this->load($index - $offset + 1, $offset - 1, $lower); } /** * {@inheritdoc} */ public function loadNext($data, $rightIndex, $upper = null) { $from = ['gt' => $data + self::DELTA]; $to = ['lt' => $data - self::DELTA]; $requestCountQuery = $this->prepareBaseRequestQuery($from, $to); $requestCountQuery = array_merge_recursive( $requestCountQuery, ['size' => 0] ); $queryCountResult = $this->connectionManager->getConnection() ->query($requestCountQuery); $offset = $queryCountResult['hits']['total']; if (!$offset) { return false; } $from = ['gte' => $data - self::DELTA]; if ($upper !== null) { $to = ['lt' => $data - self::DELTA]; } $requestQuery = $requestCountQuery; $requestCountQuery['body']['query']['bool']['filter']['bool']['must']['range'] = [$this->fieldName => array_merge($from, $to)]; $requestCountQuery['body']['from'] = $offset - 1; $requestCountQuery['body']['size'] = $rightIndex - $offset + 1; $queryResult = $this->connectionManager->getConnection() ->query($requestQuery); return array_reverse($this->arrayValuesToFloat($queryResult['hits']['hits'], $this->fieldName)); } /** * Conver array values to float type. * * @param array $hits * @param string $fieldName * * @return float[] */ private function arrayValuesToFloat(array $hits, string $fieldName): array { $returnPrices = []; foreach ($hits as $hit) { $returnPrices[] = (float)$hit['fields'][$fieldName][0]; } return $returnPrices; } /** * Prepare base query for search. * * @param array|null $from * @param array|null $to * @return array */ private function prepareBaseRequestQuery($from = null, $to = null): array { $requestQuery = [ 'index' => $this->searchIndexNameResolver->getIndexName($this->storeId, Fulltext::INDEXER_ID), 'type' => $this->clientConfig->getEntityType(), 'body' => [ 'stored_fields' => [ '_id', ], 'query' => [ 'bool' => [ 'must' => [ 'match_all' => new \stdClass(), ], 'filter' => [ 'bool' => [ 'must' => [ [ 'terms' => [ '_id' => $this->entityIds, ], ], [ 'range' => [ $this->fieldName => array_merge($from, $to), ], ], ], ], ], ], ], 'sort' => [ $this->fieldName, ], ], ]; return $requestQuery; } }