Index: src/wp-includes/query.php
===================================================================
--- src/wp-includes/query.php	(revision 27468)
+++ src/wp-includes/query.php	(working copy)
@@ -1973,15 +1973,38 @@
 			}
 		}
 
+		/**
+		 * Filter the fields used when searching the posts table.
+		 *
+		 * By default, a search on the posts table will use post_title and
+		 * post_content. This filter is available to expand that search to
+		 * other applicable fields.
+		 *
+		 * Allowed fields are post_content, post_title, post_excerpt, and post_name.
+		 *
+		 * @since 3.9.0
+		 *
+		 * @param array $fields Fields from a list of allowed search fields.
+		 */
+		$fields = apply_filters( 'query_search_fields', array( 'post_title', 'post_content' ) );
+		$allowed_search_fields = array( 'post_content', 'post_title', 'post_excerpt', 'post_name' );
+		$or = array();
+		foreach( (array) $fields as $field ) {
+			if ( in_array( $field, $allowed_search_fields ) ) {
+				$or[] = "( $wpdb->posts.$field" . ' LIKE \'%1$s\')';
+			}
+		}
+		$conditions = join( ' OR ', $or );
+
 		$n = ! empty( $q['exact'] ) ? '' : '%';
 		$searchand = '';
 		$q['search_orderby_title'] = array();
 		foreach ( $q['search_terms'] as $term ) {
 			$term = like_escape( esc_sql( $term ) );
-			if ( $n )
+			if ( $n ) {
 				$q['search_orderby_title'][] = "$wpdb->posts.post_title LIKE '%$term%'";
-
-			$search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
+			}
+			$search .= "{$searchand}(" . sprintf( $conditions, "{$n}{$term}{$n}" ) . ")";
 			$searchand = ' AND ';
 		}
 
Index: tests/phpunit/tests/query/search.php
===================================================================
--- tests/phpunit/tests/query/search.php	(revision 0)
+++ tests/phpunit/tests/query/search.php	(working copy)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Search functionality
+ *
+ * @group query
+ * @group search
+ */
+class Tests_Query_Search extends WP_UnitTestCase {
+
+	function test_search_by_fields() {
+		$post_id = $this->factory->post->create( array( 'post_title' => 'Taco', 'post_name' => 'burrito', 'post_content' => 'Enchilada', 'post_excerpt' => 'Torta' ) );
+
+		// post title
+		$q1 = new WP_Query( array( 's' => 'taco', 'fields' => 'ids' ) );
+		$this->assertEquals( array( $post_id ), $q1->posts );
+
+		// post content
+		$q2 = new WP_Query( array( 's' => 'enchilada', 'fields' => 'ids' ) );
+		$this->assertEquals( array( $post_id ), $q2->posts );
+
+		// post slug
+		$q3 = new WP_Query( array( 's' => 'Burrito', 'fields' => 'ids' ) );
+		$this->assertEquals( array(), $q3->posts );
+
+		// post excerpt
+		$q4 = new WP_Query( array( 's' => 'Torta', 'fields' => 'ids' ) );
+		$this->assertEquals( array(), $q4->posts );
+
+		add_filter( 'query_search_fields', array( $this, 'filter_query_search_fields' ) );
+		$q5 = new WP_Query( array( 's' => 'Burrito', 'fields' => 'ids' ) );
+		$this->assertEquals( array( $post_id ), $q5->posts );
+
+		$q6 = new WP_Query( array( 's' => 'Torta', 'fields' => 'ids' ) );
+		$this->assertEquals( array( $post_id ), $q6->posts );
+		remove_filter( 'query_search_fields', array( $this, 'filter_query_search_fields' ) );
+	}
+
+	function filter_query_search_fields( $fields ) {
+		$fields[] = "post_name";
+		$fields[] = "post_excerpt";
+		return $fields;
+	}
+}
\ No newline at end of file
