queryBuilder = $queryBuilder; $this->matchQueryBuilder = $matchQueryBuilder; $this->filterBuilder = $filterBuilder; } /** * Build adapter dependent query * * @param RequestInterface $request * @return array * @since 100.2.2 */ public function buildQuery(RequestInterface $request) { $searchQuery = $this->queryBuilder->initQuery($request); $searchQuery['body']['query'] = array_merge( $searchQuery['body']['query'], $this->processQuery( $request->getQuery(), [], BoolQuery::QUERY_CONDITION_MUST ) ); if (isset($searchQuery['body']['query']['bool']['should'])) { $searchQuery['body']['query']['bool']['minimum_should_match'] = 1; } $searchQuery = $this->queryBuilder->initAggregations($request, $searchQuery); return $searchQuery; } /** * Process query * * @param RequestQueryInterface $requestQuery * @param array $selectQuery * @param string $conditionType * @return array * @throws \InvalidArgumentException * @since 100.2.2 */ protected function processQuery( RequestQueryInterface $requestQuery, array $selectQuery, $conditionType ) { switch ($requestQuery->getType()) { case RequestQueryInterface::TYPE_MATCH: /** @var MatchQuery $requestQuery */ $selectQuery = $this->matchQueryBuilder->build( $selectQuery, $requestQuery, $conditionType ); break; case RequestQueryInterface::TYPE_BOOL: /** @var BoolQuery $requestQuery */ $selectQuery = $this->processBoolQuery($requestQuery, $selectQuery); break; case RequestQueryInterface::TYPE_FILTER: /** @var FilterQuery $requestQuery */ $selectQuery = $this->processFilterQuery($requestQuery, $selectQuery, $conditionType); break; default: throw new \InvalidArgumentException(sprintf('Unknown query type \'%s\'', $requestQuery->getType())); } return $selectQuery; } /** * Process bool query * * @param BoolQuery $query * @param array $selectQuery * @return array * @since 100.2.2 */ protected function processBoolQuery( BoolQuery $query, array $selectQuery ) { $selectQuery = $this->processBoolQueryCondition( $query->getMust(), $selectQuery, BoolQuery::QUERY_CONDITION_MUST ); $selectQuery = $this->processBoolQueryCondition( $query->getShould(), $selectQuery, BoolQuery::QUERY_CONDITION_SHOULD ); $selectQuery = $this->processBoolQueryCondition( $query->getMustNot(), $selectQuery, BoolQuery::QUERY_CONDITION_NOT ); return $selectQuery; } /** * Process bool query condition (must, should, must_not) * * @param RequestQueryInterface[] $subQueryList * @param array $selectQuery * @param string $conditionType * @return array * @since 100.2.2 */ protected function processBoolQueryCondition( array $subQueryList, array $selectQuery, $conditionType ) { foreach ($subQueryList as $subQuery) { $selectQuery = $this->processQuery($subQuery, $selectQuery, $conditionType); } return $selectQuery; } /** * Process filter query * * @param FilterQuery $query * @param array $selectQuery * @param string $conditionType * @return array */ private function processFilterQuery( FilterQuery $query, array $selectQuery, $conditionType ) { switch ($query->getReferenceType()) { case FilterQuery::REFERENCE_QUERY: $selectQuery = $this->processQuery($query->getReference(), $selectQuery, $conditionType); break; case FilterQuery::REFERENCE_FILTER: $conditionType = $conditionType === BoolQuery::QUERY_CONDITION_NOT ? MatchQueryBuilder::QUERY_CONDITION_MUST_NOT : $conditionType; $filterQuery = $this->filterBuilder->build($query->getReference(), $conditionType); foreach ($filterQuery['bool'] as $condition => $filter) { $selectQuery['bool'][$condition]= array_merge( isset($selectQuery['bool'][$condition]) ? $selectQuery['bool'][$condition] : [], $filter ); } break; } return $selectQuery; } }