/**
  * Run a Search Query
  *
  * @param Query $obj_query
  * @return object
  * @throws ApplicationError
  * @throws \Exception
  */
 public function search(Query $obj_query)
 {
     $obj_request = new SearchRequest();
     $obj_params = $this->prepareRequestParams($obj_request);
     // Basics
     $obj_params->setQuery($obj_query->getQuery())->setLimit($obj_query->getLimit())->setOffset($obj_query->getOffset());
     // Sorting
     $arr_sorts = $obj_query->getSorts();
     if (null !== $arr_sorts && count($arr_sorts) > 0) {
         foreach ($arr_sorts as $arr_sort) {
             $obj_sort = $obj_params->addSortSpec();
             $obj_sort->setSortExpression($arr_sort[0]);
             $obj_sort->setSortDescending(Query::DESC === $arr_sort[1]);
         }
     }
     // Match Scoring
     if (Query::SCORE_REGULAR === $obj_query->getScorer()) {
         $obj_params->mutableScorerSpec()->setScorer(Scorer::MATCH_SCORER)->setLimit($obj_query->getLimit());
     } elseif (Query::SCORE_RESCORING === $obj_query->getScorer()) {
         $obj_params->mutableScorerSpec()->setScorer(Scorer::RESCORING_MATCH_SCORER)->setLimit($obj_query->getLimit());
     }
     // Return Fields
     $arr_return_fields = $obj_query->getReturnFields();
     if (null !== $arr_return_fields && count($arr_return_fields) > 0) {
         $obj_fields = $obj_params->mutableFieldSpec();
         foreach ($arr_return_fields as $str_field) {
             $obj_fields->addName($str_field);
         }
     }
     // Return Expressions
     $arr_return_exps = $obj_query->getReturnExpressions();
     if (null !== $arr_return_exps && count($arr_return_exps) > 0) {
         $obj_fields = $obj_params->mutableFieldSpec();
         foreach ($arr_return_exps as $arr_exp) {
             $obj_fields->addExpression()->setName($arr_exp[0])->setExpression($arr_exp[1]);
         }
     }
     // Facets
     $arr_facets = $obj_query->getFacets();
     if (null !== $arr_facets) {
         if (count($arr_facets) > 0) {
             // We want a specific set of facets in the response
             foreach ($arr_facets as $str_facet) {
                 $obj_params->addIncludeFacet()->setName($str_facet);
             }
         } else {
             // We want all facets back...
             $obj_params->setAutoDiscoverFacetCount(100);
         }
     }
     $this->execute('Search', $obj_request, new SearchResponse());
     return $this->processSearchResponse();
 }