diff --git a/includes/classes/Feature/DidYouMean/DidYouMean.php b/includes/classes/Feature/DidYouMean/DidYouMean.php index 8c084d990..6ca22a50b 100644 --- a/includes/classes/Feature/DidYouMean/DidYouMean.php +++ b/includes/classes/Feature/DidYouMean/DidYouMean.php @@ -87,21 +87,27 @@ public function add_mapping( $mapping ): array { ]; if ( version_compare( (string) Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) { - $mapping['mappings']['post']['properties']['post_content']['fields'] = [ - 'shingle' => [ - 'type' => 'text', - 'analyzer' => 'trigram', - ], - ]; + $mapping_properties = &$mapping['mappings']['post']['properties']; } else { - $mapping['mappings']['properties']['post_content']['fields'] = [ - 'shingle' => [ - 'type' => 'text', - 'analyzer' => 'trigram', - ], - ]; + $mapping_properties = &$mapping['mappings']['properties']; + } + + foreach ( [ 'post_content', 'post_title' ] as $source_field ) { + $existing_copy_to = $mapping_properties[ $source_field ]['copy_to'] ?? []; + $existing_copy_to = is_array( $existing_copy_to ) ? $existing_copy_to : [ $existing_copy_to ]; + + if ( ! in_array( 'ep_did_you_mean', $existing_copy_to, true ) ) { + $existing_copy_to[] = 'ep_did_you_mean'; + } + + $mapping_properties[ $source_field ]['copy_to'] = $existing_copy_to; } + $mapping_properties['ep_did_you_mean'] = [ + 'type' => 'text', + 'analyzer' => 'trigram', + ]; + return $mapping; } @@ -160,11 +166,11 @@ public function get_suggestion( $query = null ) { public function add_query_args( $formatted_args, $args, $wp_query ): array { $search_analyzer = [ 'phrase' => [ - 'field' => 'post_content.shingle', + 'field' => 'ep_did_you_mean', 'max_errors' => 2, 'direct_generator' => [ [ - 'field' => 'post_content.shingle', + 'field' => 'ep_did_you_mean', ], ], ], diff --git a/tests/php/features/TestDidYouMean.php b/tests/php/features/TestDidYouMean.php index b1d3e7e64..b18da14ee 100644 --- a/tests/php/features/TestDidYouMean.php +++ b/tests/php/features/TestDidYouMean.php @@ -197,13 +197,12 @@ function () { $mapping = ElasticPress\Indexables::factory()->get( 'post' )->generate_mapping(); $expected_result = [ - 'shingle' => - [ - 'type' => 'text', - 'analyzer' => 'trigram', - ], + 'type' => 'text', + 'analyzer' => 'trigram', ]; - $this->assertSame( $expected_result, $mapping['mappings']['properties']['post_content']['fields'] ); + $this->assertSame( [ 'ep_did_you_mean' ], $mapping['mappings']['properties']['post_content']['copy_to'] ); + $this->assertSame( [ 'ep_did_you_mean' ], $mapping['mappings']['properties']['post_title']['copy_to'] ); + $this->assertSame( $expected_result, $mapping['mappings']['properties']['ep_did_you_mean'] ); } /** @@ -220,13 +219,58 @@ function () { $mapping = ElasticPress\Indexables::factory()->get( 'post' )->generate_mapping(); $expected_result = [ - 'shingle' => - [ - 'type' => 'text', - 'analyzer' => 'trigram', - ], + 'type' => 'text', + 'analyzer' => 'trigram', ]; - $this->assertSame( $expected_result, $mapping['mappings']['post']['properties']['post_content']['fields'] ); + $this->assertSame( [ 'ep_did_you_mean' ], $mapping['mappings']['post']['properties']['post_content']['copy_to'] ); + $this->assertSame( [ 'ep_did_you_mean' ], $mapping['mappings']['post']['properties']['post_title']['copy_to'] ); + $this->assertSame( $expected_result, $mapping['mappings']['post']['properties']['ep_did_you_mean'] ); + } + + /** + * Tests that ES returns a suggestion based on post title when content does not contain the term. + */ + public function testEsSearchSuggestionFromTitle() { + $this->ep_factory->post->create( + [ + 'post_title' => 'Sleek Cotton Shirt', + 'post_content' => '', + ] + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + $query = new \WP_Query( + [ + 's' => 'shir', + ] + ); + + $this->assertTrue( $query->elasticsearch_success ); + $this->assertEquals( 'shirt', $query->suggested_terms['options'][0]['text'] ); + } + + /** + * Tests that ES returns a suggestion when content is present but title is the source. + */ + public function testEsSearchSuggestionFromTitleWithContent() { + $this->ep_factory->post->create( + [ + 'post_title' => 'Sleek Cotton Shirt', + 'post_content' => 'Some generic content', + ] + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + $query = new \WP_Query( + [ + 's' => 'shir', + ] + ); + + $this->assertTrue( $query->elasticsearch_success ); + $this->assertEquals( 'shirt', $query->suggested_terms['options'][0]['text'] ); } /**