From 974abf2d6ed1e6a8ffd78633dc46c962c41cfb74 Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Fri, 15 May 2020 11:32:51 -0600 Subject: [PATCH 01/14] Add VIP Search adapter --- adapters/vip-search.php | 261 ++++++++++++++++++++++++++++++++++++++++ functions.php | 4 +- 2 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 adapters/vip-search.php diff --git a/adapters/vip-search.php b/adapters/vip-search.php new file mode 100644 index 0000000..b9ff481 --- /dev/null +++ b/adapters/vip-search.php @@ -0,0 +1,261 @@ +query_es( 'post', $es_args ); + + return $result; + } + } + } + + /** + * Sets the posts array to the list of found post IDs. + * + * @param array $q Query arguments. + * @param array|WP_Error $es_response Response from VIP Search. + * @access protected + */ + protected function set_posts( $q, $es_response ) { + $this->posts = array(); + if ( ! is_wp_error( $es_response ) && isset( $es_response['documents'] ) ) { + switch ( $q['fields'] ) { + case 'ids': + foreach ( $es_response['documents'] as $hit ) { + $post_id = (array) $hit[ $this->es_map( 'post_id' ) ]; + $this->posts[] = reset( $post_id ); + } + return; + + case 'id=>parent': + foreach ( $es_response['documents'] as $hit ) { + $post_id = (array) $hit[ $this->es_map( 'post_id' ) ]; + $post_parent = (array) $hit[ $this->es_map( 'post_parent' ) ]; + $this->posts[ reset( $post_id ) ] = reset( $post_parent ); + } + return; + + default: + if ( apply_filters( 'es_query_use_source', false ) ) { + $this->posts = wp_list_pluck( $es_response['documents'], '_source' ); + return; + } else { + $post_ids = array(); + foreach ( $es_response['documents'] as $hit ) { + $post_id = (array) $hit[ $this->es_map( 'post_id' ) ]; + $post_ids[] = absint( reset( $post_id ) ); + } + $post_ids = array_filter( $post_ids ); + if ( ! empty( $post_ids ) ) { + global $wpdb; + $post__in = implode( ',', $post_ids ); + $this->posts = $wpdb->get_results( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN ($post__in) ORDER BY FIELD( {$wpdb->posts}.ID, $post__in )" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.VIP.DirectDatabaseQuery.NoCaching, WordPress.VIP.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery + } + return; + } + } + } else { + $this->posts = array(); + } + } + + /** + * Set up the amount of found posts and the number of pages (if limit clause was used) + * for the current query. + * + * @param array $q Query arguments. + * @param array|WP_Error $es_response The response from the Elasticsearch server. + * @access public + */ + public function set_found_posts( $q, $es_response ) { + if ( ! is_wp_error( $es_response ) && isset( $es_response['found_documents']['value'] ) ) { + $this->found_posts = absint( $es_response['found_documents']['value'] ); + } else { + $this->found_posts = 0; + } + $this->found_posts = apply_filters_ref_array( 'es_found_posts', array( $this->found_posts, &$this ) ); + $this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] ); + } +} + +/** + * Maps Elasticsearch DSL keys to their VIP-specific naming conventions. + * + * @param array $es_map Additional fields to map. + * @return array The final field mapping. + */ +function vip_es_field_map( $es_map ) { + return wp_parse_args( + array( + 'post_author' => 'post_author.id', + 'post_author.user_nicename' => 'post_author.display_name', + 'post_date' => 'post_date', + 'post_date.year' => 'date_terms.year', + 'post_date.month' => 'date_terms.month', + 'post_date.week' => 'date_terms.week', + 'post_date.day' => 'date_terms.day', + 'post_date.day_of_year' => 'date_terms.dayofyear', + 'post_date.day_of_week' => 'date_terms.dayofweek', + 'post_date.hour' => 'date_terms.hour', + 'post_date.minute' => 'date_terms.minute', + 'post_date.second' => 'date_terms.second', + 'post_date_gmt' => 'post_date_gmt', + 'post_date_gmt.year' => 'date_gmt_terms.year', + 'post_date_gmt.month' => 'date_gmt_terms.month', + 'post_date_gmt.week' => 'date_gmt_terms.week', + 'post_date_gmt.day' => 'date_gmt_terms.day', + 'post_date_gmt.day_of_year' => 'date_gmt_terms.day_of_year', + 'post_date_gmt.day_of_week' => 'date_gmt_terms.day_of_week', + 'post_date_gmt.hour' => 'date_gmt_terms.hour', + 'post_date_gmt.minute' => 'date_gmt_terms.minute', + 'post_date_gmt.second' => 'date_gmt_terms.second', + 'post_content' => 'post_content', + 'post_content.analyzed' => 'post_content', + 'post_title' => 'post_title', + 'post_title.analyzed' => 'post_title', + 'post_excerpt' => 'post_excerpt', + 'post_password' => 'post_password', // This isn't indexed on VIP. + 'post_name' => 'post_name', + 'post_modified' => 'post_modified', + 'post_modified.year' => 'modified_date_terms.year', + 'post_modified.month' => 'modified_date_terms.month', + 'post_modified.week' => 'modified_date_terms.week', + 'post_modified.day' => 'modified_date_terms.day', + 'post_modified.day_of_year' => 'modified_date_terms.day_of_year', + 'post_modified.day_of_week' => 'modified_date_terms.day_of_week', + 'post_modified.hour' => 'modified_date_terms.hour', + 'post_modified.minute' => 'modified_date_terms.minute', + 'post_modified.second' => 'modified_date_terms.second', + 'post_modified_gmt' => 'post_modified_gmt', + 'post_modified_gmt.year' => 'modified_date_gmt_terms.year', + 'post_modified_gmt.month' => 'modified_date_gmt_terms.month', + 'post_modified_gmt.week' => 'modified_date_gmt_terms.week', + 'post_modified_gmt.day' => 'modified_date_gmt_terms.day', + 'post_modified_gmt.day_of_year' => 'modified_date_gmt_terms.day_of_year', + 'post_modified_gmt.day_of_week' => 'modified_date_gmt_terms.day_of_week', + 'post_modified_gmt.hour' => 'modified_date_gmt_terms.hour', + 'post_modified_gmt.minute' => 'modified_date_gmt_terms.minute', + 'post_modified_gmt.second' => 'modified_date_gmt_terms.second', + 'post_parent' => 'post_parent', + 'menu_order' => 'menu_order', + 'post_mime_type' => 'post_mime_type', + 'comment_count' => 'comment_count', + 'post_meta' => 'meta.%s.value', + 'post_meta.analyzed' => 'meta.%s.value', + 'post_meta.long' => 'meta.%s.long', + 'post_meta.double' => 'meta.%s.double', + 'post_meta.binary' => 'meta.%s.boolean', + 'term_id' => 'terms.%s.term_id', + 'term_slug' => 'terms.%s.slug', + 'term_name' => 'terms.%s.name', + 'category_id' => 'terms.category.term_id', + 'category_slug' => 'terms.category.slug', + 'category_name' => 'terms.category.name', + 'tag_id' => 'terms.tag.term_id', + 'tag_slug' => 'terms.tag.slug', + 'tag_name' => 'terms.tag.name', + ), + $es_map + ); +} +add_filter( 'es_field_map', 'vip_es_field_map' ); + +/** + * Advanced Post Cache and es-wp-query do not work well together. In + * particular, the WP_Query->found_posts attribute gets corrupted when using + * both of these plugins, so here we disable Advanced Post Cache completely + * when queries are being made using Elasticsearch. + * + * On the other hand, if a non-Elasticsearch query is run, and we disabled + * Advanced Post Cache earlier, we enable it again, to make use of its caching + * features. + * + * Note that this applies only to calls done via WP_Query(), and not + * ES_WP_Query() + * + * @param WP_Query|ES_WP_Query|ES_WP_Query_Wrapper $query The query to examine. + */ +function vip_es_disable_advanced_post_cache( &$query ) { + global $advanced_post_cache_object; + + static $disabled_apc = false; + + if ( empty( $advanced_post_cache_object ) || ! is_object( $advanced_post_cache_object ) ) { + return; + } + + /* + * These two might be passsed to us; we only + * handle WP_Query, so ignore these. + */ + if ( + ( $query instanceof ES_WP_Query_Wrapper ) || + ( $query instanceof ES_WP_Query ) + ) { + return; + } + + if ( $query->get( 'es' ) ) { + if ( true === $disabled_apc ) { + // Already disabled, don't try again. + return; + } + + /* + * An Elasticsearch-enabled query is being run. Disable Advanced Post Cache + * entirely. + * + * Note that there is one action-hook that is not deactivated: The switch_blog + * action is not deactivated, because it might be called in-between + * Elasticsearch-enabled query, and a non-Elasticsearch query, and because it + * does not have an effect on WP_Query()-results directly. + */ + + remove_filter( 'posts_request', array( $advanced_post_cache_object, 'posts_request' ) ); + remove_filter( 'posts_results', array( $advanced_post_cache_object, 'posts_results' ) ); + + remove_filter( 'post_limits_request', array( $advanced_post_cache_object, 'post_limits_request' ), 999 ); + + remove_filter( 'found_posts_query', array( $advanced_post_cache_object, 'found_posts_query' ) ); + remove_filter( 'found_posts', array( $advanced_post_cache_object, 'found_posts' ) ); + + $disabled_apc = true; + } else { + // A non-ES query. + if ( true === $disabled_apc ) { + /* + * Earlier, we disabled Advanced Post Cache + * entirely, but now a non-Elasticsearch query is + * being run, and in such cases it might be useful + * to have the Cache enabled. Here we enable + * it again. + */ + $advanced_post_cache_object->__construct(); + + $disabled_apc = false; + } + } +} +add_action( 'pre_get_posts', 'vip_es_disable_advanced_post_cache', -100 ); diff --git a/functions.php b/functions.php index 8f98d94..3bbe9e7 100644 --- a/functions.php +++ b/functions.php @@ -79,11 +79,11 @@ function es_get_posts( $args = null ) { /** * Loads one of the included adapters. * - * @param string $adapter Which adapter to include. Currently allows searchpress, wpcom-vip, travis and jetpack-search. + * @param string $adapter Which adapter to include. Currently allows searchpress, wpcom-vip, travis, jetpack-search, and vip-search. * @return void */ function es_wp_query_load_adapter( $adapter ) { - if ( in_array( $adapter, array( 'searchpress', 'wpcom-vip', 'travis', 'jetpack-search' ), true ) ) { + if ( in_array( $adapter, array( 'searchpress', 'wpcom-vip', 'travis', 'jetpack-search', 'vip-search' ), true ) ) { require_once ES_WP_QUERY_PATH . "/adapters/{$adapter}.php"; } } From 4f8462cd6a8c5e6134b792e362f799923b168e42 Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Mon, 18 May 2020 16:26:33 -0600 Subject: [PATCH 02/14] Fix tag taxonomy name in fields mapping The Tag taxonomy is actually called `post_tag` --- adapters/vip-search.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index b9ff481..31ef997 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -173,9 +173,9 @@ function vip_es_field_map( $es_map ) { 'category_id' => 'terms.category.term_id', 'category_slug' => 'terms.category.slug', 'category_name' => 'terms.category.name', - 'tag_id' => 'terms.tag.term_id', - 'tag_slug' => 'terms.tag.slug', - 'tag_name' => 'terms.tag.name', + 'tag_id' => 'terms.post_tag.term_id', + 'tag_slug' => 'terms.post_tag.slug', + 'tag_name' => 'terms.post_tag.name', ), $es_map ); From 244c038bd9ccc12600f5e750904655b2bdff2745 Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Fri, 5 Jun 2020 15:39:56 -0400 Subject: [PATCH 03/14] Account for a new total format in es67 --- class-es-wp-query-wrapper.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/class-es-wp-query-wrapper.php b/class-es-wp-query-wrapper.php index 6ddbe6a..f0c9c2b 100644 --- a/class-es-wp-query-wrapper.php +++ b/class-es-wp-query-wrapper.php @@ -169,7 +169,9 @@ protected function no_results() { * @access public */ public function set_found_posts( $q, $es_response ) { - if ( isset( $es_response['hits']['total'] ) ) { + if ( isset( $es_response['hits']['total']['value'] ) ) { + $this->found_posts = absint( $es_response['hits']['total']['value'] ); + } elseif ( isset( $es_response['hits']['total'] ) ) { $this->found_posts = absint( $es_response['hits']['total'] ); } else { $this->found_posts = 0; @@ -253,7 +255,7 @@ public function get_posts() { 'tag_slug' => 'terms.%s.slug', 'tag_name' => 'terms.%s.name', 'tag_tt_id' => 'terms.%s.term_taxonomy_id', - ) + ) ); $this->parse_query(); @@ -424,7 +426,7 @@ public function get_posts() { 'after' => $date, 'before' => $date, 'inclusive' => true, - ) + ) ); $date_filter = $date_query->get_dsl( $this ); if ( ! empty( $date_filter ) ) { @@ -995,8 +997,8 @@ public function get_posts() { array( 'protected' => true, 'show_in_admin_all_list' => true, - ) - ) + ) + ) ); } @@ -1153,7 +1155,7 @@ public function get_posts() { 'fields' => $fields, 'size' => $size, 'from' => $from, - ) + ) ); // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. @@ -1312,7 +1314,7 @@ public function get_posts() { 'post_type' => $post_type, 'post_status' => 'publish', 'nopaging' => true, // phpcs:ignore WordPress.VIP.PostsPerPage.posts_per_page_nopaging - ) + ) ); foreach ( $stickies as $sticky_post ) { @@ -1635,7 +1637,7 @@ public static function dsl_multi_match( $fields, $query, $args = array() ) { 'query' => $query, 'fields' => (array) $fields, ), - $args + $args ), ); } From d0dc7d02766cb642c6f9c84fe1798d649fc3b67e Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Fri, 12 Jun 2020 14:55:13 -0600 Subject: [PATCH 04/14] Use raw post type for post_type field Otherwise filters don't work correctly --- adapters/vip-search.php | 1 + 1 file changed, 1 insertion(+) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index 31ef997..dd84f6c 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -135,6 +135,7 @@ function vip_es_field_map( $es_map ) { 'post_content.analyzed' => 'post_content', 'post_title' => 'post_title', 'post_title.analyzed' => 'post_title', + 'post_type' => 'post_type.raw', 'post_excerpt' => 'post_excerpt', 'post_password' => 'post_password', // This isn't indexed on VIP. 'post_name' => 'post_name', From 39e0096506dcec93c1d0318e0788d3c79ac34dbd Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Thu, 25 Jun 2020 12:08:32 -0600 Subject: [PATCH 05/14] Use the lowercase version of term names This matches WP Core and JP Search behavior for querying by term name --- adapters/vip-search.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index dd84f6c..72f7538 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -170,19 +170,36 @@ function vip_es_field_map( $es_map ) { 'post_meta.binary' => 'meta.%s.boolean', 'term_id' => 'terms.%s.term_id', 'term_slug' => 'terms.%s.slug', - 'term_name' => 'terms.%s.name', + 'term_name' => 'terms.%s.name.sortable', 'category_id' => 'terms.category.term_id', 'category_slug' => 'terms.category.slug', - 'category_name' => 'terms.category.name', + 'category_name' => 'terms.category.name.sortable', 'tag_id' => 'terms.post_tag.term_id', 'tag_slug' => 'terms.post_tag.slug', - 'tag_name' => 'terms.post_tag.name', + 'tag_name' => 'terms.post_tag.name.sortable', ), $es_map ); } add_filter( 'es_field_map', 'vip_es_field_map' ); +/** + * Normalise term name to lowercase as we are mapping that against the "sortable" field, which is a lowercased keyword. + * + * @param string|mixed $term Term's name which should be normalised to + * lowercase. + * @param string $taxonomy Taxonomy of the term. + * @return mixed If $term is a string, lowercased string is returned. Otherwise + * original value is return unchanged. + */ +function vip_es_term_name_slug_tolower( $term, $taxonomy ) { + if ( ! is_string( $term ) || empty( $term ) ) { + return $term; + } + return strtolower( $term ); +} +add_filter( 'es_tax_query_term_name', 'vip_es_term_name_slug_tolower', 10, 2 ); + /** * Advanced Post Cache and es-wp-query do not work well together. In * particular, the WP_Query->found_posts attribute gets corrupted when using From f804b03282935828ce6414406bae9c1338ce4e92 Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Thu, 25 Jun 2020 12:10:22 -0600 Subject: [PATCH 06/14] User lowercase meta values This matches existing behavior of JP Search --- adapters/vip-search.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index 72f7538..ca962f4 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -163,7 +163,7 @@ function vip_es_field_map( $es_map ) { 'menu_order' => 'menu_order', 'post_mime_type' => 'post_mime_type', 'comment_count' => 'comment_count', - 'post_meta' => 'meta.%s.value', + 'post_meta' => 'meta.%s.value.sortable', 'post_meta.analyzed' => 'meta.%s.value', 'post_meta.long' => 'meta.%s.long', 'post_meta.double' => 'meta.%s.double', @@ -183,6 +183,23 @@ function vip_es_field_map( $es_map ) { } add_filter( 'es_field_map', 'vip_es_field_map' ); +/** + * Returns the lowercase version of a meta value. + * + * @param mixed $meta_value The meta value. + * @param string $meta_key The meta key. + * @param string $meta_compare The comparison operation. + * @param string $meta_type The type of meta (post, user, term, etc). + * @return mixed If value is a string, returns the lowercase version. Otherwise, returns the original value, unmodified. + */ +function vip_es_meta_value_tolower( $meta_value, $meta_key, $meta_compare, $meta_type ) { + if ( ! is_string( $meta_value ) || empty( $meta_value ) ) { + return $meta_value; + } + return strtolower( $meta_value ); +} +add_filter( 'es_meta_query_meta_value', 'vip_es_meta_value_tolower', 10, 4 ); + /** * Normalise term name to lowercase as we are mapping that against the "sortable" field, which is a lowercased keyword. * From d7dc843c276c45398cdb6987de0c957b84438660 Mon Sep 17 00:00:00 2001 From: Kyle Benk Date: Mon, 18 Feb 2019 14:15:03 -0500 Subject: [PATCH 07/14] Ensure we can return just the _source fields if desired --- class-es-wp-query-wrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class-es-wp-query-wrapper.php b/class-es-wp-query-wrapper.php index f0c9c2b..bd072cd 100644 --- a/class-es-wp-query-wrapper.php +++ b/class-es-wp-query-wrapper.php @@ -1207,7 +1207,7 @@ public function get_posts() { $this->es_args = apply_filters_ref_array( 'es_posts_request', array( $this->es_args, &$this ) ); } - if ( 'ids' === $q['fields'] || 'id=>parent' === $q['fields'] ) { + if ( 'ids' === $q['fields'] || 'id=>parent' === $q['fields'] || apply_filters( 'es_query_use_source', false ) ) { $this->es_response = $this->query_es( $this->es_args ); $this->set_posts( $q, $this->es_response ); $this->post_count = count( $this->posts ); From ad0b31aa279bd134e67b113833ea4265abf414e7 Mon Sep 17 00:00:00 2001 From: Nick Daugherty Date: Wed, 9 Sep 2020 15:20:24 -0600 Subject: [PATCH 08/14] Return total hits by default Elasticsearch after 7.0 doesn't return the total hits by default - it caps the count at 10k. That reduces query times, but also makes the count inaccurate when more than 10k posts match, so we need to send the `track_total_hits` parameter. --- class-es-wp-query-wrapper.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/class-es-wp-query-wrapper.php b/class-es-wp-query-wrapper.php index bd072cd..a333106 100644 --- a/class-es-wp-query-wrapper.php +++ b/class-es-wp-query-wrapper.php @@ -1202,6 +1202,9 @@ public function get_posts() { $size = apply_filters( 'es_query_max_results', 1000 ); $this->es_args['size'] = $size; } + + // ES > 7.0 doesn't return the actual total hits by default (capped at 10k), but we need accurate counts + $this->es_args[ 'track_total_hits' ] = true; if ( ! $q['suppress_filters'] ) { $this->es_args = apply_filters_ref_array( 'es_posts_request', array( $this->es_args, &$this ) ); From 6644e1b3f6eb7e048be066108ee6e637b66c24b3 Mon Sep 17 00:00:00 2001 From: Brandon Skinner Date: Thu, 17 Sep 2020 12:58:03 -0600 Subject: [PATCH 09/14] Use raw field for post title in adapter --- adapters/vip-search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index ca962f4..e6f8297 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -133,7 +133,7 @@ function vip_es_field_map( $es_map ) { 'post_date_gmt.second' => 'date_gmt_terms.second', 'post_content' => 'post_content', 'post_content.analyzed' => 'post_content', - 'post_title' => 'post_title', + 'post_title' => 'post_title.raw', 'post_title.analyzed' => 'post_title', 'post_type' => 'post_type.raw', 'post_excerpt' => 'post_excerpt', From 5918926f8d7f4c3ecaa27d184d8e6a2f7a73082c Mon Sep 17 00:00:00 2001 From: Todd Wright <4177859+t-wright@users.noreply.github.com> Date: Mon, 21 Sep 2020 16:12:31 +1000 Subject: [PATCH 10/14] Use raw field for post name in adapter --- adapters/vip-search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index e6f8297..25f086d 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -138,7 +138,7 @@ function vip_es_field_map( $es_map ) { 'post_type' => 'post_type.raw', 'post_excerpt' => 'post_excerpt', 'post_password' => 'post_password', // This isn't indexed on VIP. - 'post_name' => 'post_name', + 'post_name' => 'post_name.raw', 'post_modified' => 'post_modified', 'post_modified.year' => 'modified_date_terms.year', 'post_modified.month' => 'modified_date_terms.month', From dc95da41b00ba0e5bb4bdeeba48c9537a1c65780 Mon Sep 17 00:00:00 2001 From: Rebecca Hum <16962021+rebeccahum@users.noreply.github.com> Date: Mon, 5 Oct 2020 12:24:29 -0600 Subject: [PATCH 11/14] Fix is_main_query() not registering when hooked onto pre_get_posts --- class-es-wp-query-shoehorn.php | 3 ++- class-es-wp-query-wrapper.php | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/class-es-wp-query-shoehorn.php b/class-es-wp-query-shoehorn.php index 678c8d8..838200e 100644 --- a/class-es-wp-query-shoehorn.php +++ b/class-es-wp-query-shoehorn.php @@ -24,7 +24,7 @@ function es_wp_query_arg( $vars ) { * If a WP_Query object has `'es' => true`, use Elasticsearch to run the meat of the query. * This is fires on the "pre_get_posts" action. * - * @param object $query WP_Query object. + * @param WP_Query $query Current full WP_Query object. * @return void */ function es_wp_query_shoehorn( &$query ) { @@ -78,6 +78,7 @@ function es_wp_query_shoehorn( &$query ) { */ $es_query_args = $query->query; $es_query_args['fields'] = 'ids'; + $es_query_args['es_is_main_query'] = $query->is_main_query(); $es_query = new ES_WP_Query( $es_query_args ); // Make the post query use the post IDs from the ES results instead. diff --git a/class-es-wp-query-wrapper.php b/class-es-wp-query-wrapper.php index a333106..110cff6 100644 --- a/class-es-wp-query-wrapper.php +++ b/class-es-wp-query-wrapper.php @@ -43,6 +43,19 @@ abstract class ES_WP_Query_Wrapper extends WP_Query { */ abstract protected function query_es( $es_args ); + /** + * Override default WP_Query->is_main_query() to support + * this conditional when the main query has been overridden + * by this class. + * + * @fixes #38 + * + * @return bool + */ + public function is_main_query() { + return $this->get( 'es_is_main_query', false ); + } + /** * Maps a field to its Elasticsearch context. * From d660b997a6b8e1b903aeaa6336282db4691981b6 Mon Sep 17 00:00:00 2001 From: Rebecca Hum <16962021+rebeccahum@users.noreply.github.com> Date: Fri, 16 Oct 2020 14:11:10 -0600 Subject: [PATCH 12/14] Use login field instead of display_name for cases where user's display_name is not 1:1 with nicename --- adapters/vip-search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index 25f086d..89b13f5 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -110,7 +110,7 @@ function vip_es_field_map( $es_map ) { return wp_parse_args( array( 'post_author' => 'post_author.id', - 'post_author.user_nicename' => 'post_author.display_name', + 'post_author.user_nicename' => 'post_author.login', 'post_date' => 'post_date', 'post_date.year' => 'date_terms.year', 'post_date.month' => 'date_terms.month', From cc291c18217856e962a4dfec92704b637e16af2f Mon Sep 17 00:00:00 2001 From: Rebecca Hum <16962021+rebeccahum@users.noreply.github.com> Date: Tue, 20 Oct 2020 11:53:09 -0600 Subject: [PATCH 13/14] Use .raw because it's not analyzed --- adapters/vip-search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/vip-search.php b/adapters/vip-search.php index 89b13f5..c316f7b 100644 --- a/adapters/vip-search.php +++ b/adapters/vip-search.php @@ -110,7 +110,7 @@ function vip_es_field_map( $es_map ) { return wp_parse_args( array( 'post_author' => 'post_author.id', - 'post_author.user_nicename' => 'post_author.login', + 'post_author.user_nicename' => 'post_author.login.raw', 'post_date' => 'post_date', 'post_date.year' => 'date_terms.year', 'post_date.month' => 'date_terms.month', From 05a254e42d4cce8d53c2ebbcd522a2c0b3572c0b Mon Sep 17 00:00:00 2001 From: Rebecca Hum <16962021+rebeccahum@users.noreply.github.com> Date: Fri, 19 Nov 2021 08:46:14 -0700 Subject: [PATCH 14/14] Pull from mu-plugins --- class-es-wp-tax-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class-es-wp-tax-query.php b/class-es-wp-tax-query.php index 533966d..0b1ddd9 100644 --- a/class-es-wp-tax-query.php +++ b/class-es-wp-tax-query.php @@ -264,7 +264,7 @@ private function clean_query( &$query ) { return; } - $query['terms'] = array_unique( (array) $query['terms'] ); + $query['terms'] = array_values( array_unique( (array) $query['terms'] ) ); if ( is_taxonomy_hierarchical( $query['taxonomy'] ) && $query['include_children'] ) { $this->transform_query( $query, 'term_id' );