protected function query_es($es_args)
 {
     if (function_exists('es_api_search_index')) {
         return es_api_search_index($es_args, 'es-wp-query');
     }
 }
 public function filter__posts_request($sql, $query)
 {
     global $wpdb;
     if (!$query->is_main_query() || !$query->is_search()) {
         return $sql;
     }
     $page = $query->get('paged') ? absint($query->get('paged')) : 1;
     // Start building the WP-style search query args
     // They'll be translated to ES format args later
     $es_wp_query_args = array('query' => $query->get('s'), 'posts_per_page' => $query->get('posts_per_page'), 'paged' => $page, 'orderby' => $query->get('orderby'), 'order' => $query->get('order'));
     // Look for query variables that match registered and supported facets
     foreach ($this->facets as $label => $facet) {
         switch ($facet['type']) {
             case 'taxonomy':
                 $query_var = $this->get_taxonomy_query_var($this->facets[$label]['taxonomy']);
                 if (!$query_var) {
                     continue 2;
                 }
                 // switch() is considered a looping structure
                 if ($query->get($query_var)) {
                     $es_wp_query_args['terms'][$this->facets[$label]['taxonomy']] = explode(',', $query->get($query_var));
                 }
                 // This plugon's custom "categery" isn't a real query_var, so manually handle it
                 if ('category' == $query_var && !empty($_GET[$query_var])) {
                     $slugs = explode(',', $_GET[$query_var]);
                     foreach ($slugs as $slug) {
                         $es_wp_query_args['terms'][$this->facets[$label]['taxonomy']][] = $slug;
                     }
                 }
                 break;
             case 'post_type':
                 if ($query->get('post_type') && 'any' != $query->get('post_type')) {
                     $post_types_via_user = $query->get('post_type');
                 } elseif (!empty($_GET['post_type'])) {
                     $post_types_via_user = explode(',', $_GET['post_type']);
                 } else {
                     $post_types_via_user = false;
                 }
                 $post_types = array();
                 // Validate post types, making sure they exist and are public
                 if ($post_types_via_user) {
                     foreach ((array) $post_types_via_user as $post_type_via_user) {
                         $post_type_object = get_post_type_object($post_type_via_user);
                         if (!$post_type_object || $post_type_object->exclude_from_search) {
                             continue;
                         }
                         $post_types[] = $post_type_via_user;
                     }
                 }
                 // Default to all non-excluded from search post types
                 if (empty($post_types)) {
                     $post_types = array_values(get_post_types(array('exclude_from_search' => false)));
                 }
                 $es_wp_query_args['post_type'] = $post_types;
                 break;
         }
     }
     // Date
     if ($query->get('year')) {
         if ($query->get('monthnum')) {
             // Padding
             $date_monthnum = sprintf('%02d', $query->get('monthnum'));
             if ($query->get('day')) {
                 // Padding
                 $date_day = sprintf('%02d', $query->get('day'));
                 $date_start = $query->get('year') . '-' . $date_monthnum . '-' . $date_day . ' 00:00:00';
                 $date_end = $query->get('year') . '-' . $date_monthnum . '-' . $date_day . ' 23:59:59';
             } else {
                 $days_in_month = date('t', mktime(0, 0, 0, $query->get('monthnum'), 14, $query->get('year')));
                 // 14 = middle of the month so no chance of DST issues
                 $date_start = $query->get('year') . '-' . $date_monthnum . '-01 00:00:00';
                 $date_end = $query->get('year') . '-' . $date_monthnum . '-' . $days_in_month . ' 23:59:59';
             }
         } else {
             $date_start = $query->get('year') . '-01-01 00:00:00';
             $date_end = $query->get('year') . '-12-31 23:59:59';
         }
         $es_wp_query_args['date_range'] = array('field' => 'date', 'gte' => $date_start, 'lte' => $date_end);
     }
     // Facets
     if (!empty($this->facets)) {
         $es_wp_query_args['facets'] = $this->facets;
     }
     // You can use this filter to modify the search query parameters, such as controlling the post_type.
     // These arguments are in the format for wpcom_search_api_wp_to_es_args(), i.e. WP-style.
     $es_wp_query_args = apply_filters('wpcom_elasticsearch_wp_query_args', $es_wp_query_args, $query);
     // Convert the WP-style args into ES args
     $es_query_args = wpcom_search_api_wp_to_es_args($es_wp_query_args);
     $es_query_args['fields'] = array('post_id', 'blog_id');
     // Ask for a search suggestion (to catch typos)
     // See http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html for options
     $suggest_beta_blogs = array(15797879, 12269838, 2235322);
     if (in_array(get_current_blog_id(), $suggest_beta_blogs)) {
         $es_query_args['suggest'] = array('text' => $query->get('s'), 'simple_phrase' => array('phrase' => array('field' => 'content', 'direct_generator' => array(array('field' => 'content', 'suggest_mode' => 'popular', 'prefix_len' => 3, 'max_term_freq' => 0.02)))));
     }
     // This filter is harder to use if you're unfamiliar with ES but it allows complete control over the query
     $es_query_args = apply_filters('wpcom_elasticsearch_query_args', $es_query_args, $query);
     // Do the actual search query!
     $this->search_result = es_api_search_index($es_query_args, 'blog-search');
     if (is_wp_error($this->search_result) || !is_array($this->search_result) || empty($this->search_result['results']) || empty($this->search_result['results']['hits'])) {
         $this->found_posts = 0;
         return '';
     }
     // Allow filtering of entire result set to modify it or to add / remove results
     $this->search_result = apply_filters('wpcom_elasticsearch_found_posts', $this->search_result);
     // Total number of results for paging purposes
     $this->found_posts = $this->search_result['results']['total'];
     // Don't select anything, posts are inflated by ES_WPCOM_SearchResult_Posts_Iterator in The Loop,
     // to account for multi site search
     return '';
 }
 /**
  * A wrapper for es_api_search_index() that accepts WP-style args
  *
  * This is a copy/paste, up to date as of WP.com r65003 (Jan 7th, 2013)
  *
  * @param array $args
  * @param string $stat_app_name Optional.
  * @return bool|string False if WP_Error, otherwise JSON string
  * @see wpcom_search_api_wp_to_es_args() for details
  */
 function wpcom_search_api_query($args, $stat_app_name = 'blog-search')
 {
     $es_query_args = wpcom_search_api_wp_to_es_args($args);
     return es_api_search_index($es_query_args, $stat_app_name);
 }