diff --git src/wp-includes/class-wp-query.php src/wp-includes/class-wp-query.php
index 9590406..03c9ff2 100644
--- src/wp-includes/class-wp-query.php
+++ src/wp-includes/class-wp-query.php
@@ -1341,7 +1341,14 @@ class WP_Query {
 			}
 
 			$like = $n . $this->db->esc_like( $term ) . $n;
-			$search .= $this->db->prepare( "{$searchand}(({$this->db->posts}.post_title $like_op %s) $andor_op ({$this->db->posts}.post_excerpt $like_op %s) $andor_op ({$this->db->posts}.post_content $like_op %s))", $like, $like, $like );
+
+			// If this is a search for attachments, inlcude the filename in the search.
+			if ( array( 'attachment' ) === (array) $q['post_type'] ) {
+				$search .= $this->db->prepare( "{$searchand}(({$this->db->posts}.post_title $like_op %s) $andor_op ({$this->db->posts}.post_excerpt $like_op %s) $andor_op ({$this->db->posts}.post_content $like_op %s) $andor_op ({$this->db->postmeta}.meta_key = '_wp_attached_file' AND {$this->db->postmeta}.meta_value $like_op %s))", $like, $like, $like, $like );
+			} else {
+				$search .= $this->db->prepare( "{$searchand}(({$this->db->posts}.post_title $like_op %s) $andor_op ({$this->db->posts}.post_excerpt $like_op %s) $andor_op ({$this->db->posts}.post_content $like_op %s))", $like, $like, $like );
+			}
+
 			$searchand = ' AND ';
 		}
 
@@ -2068,7 +2075,7 @@ class WP_Query {
 			}
 		}
 
-		if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
+		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) || ( $this->is_search && array( 'attachment' ) === (array) $q['post_type'] ) ) {
 			$groupby = "{$this->db->posts}.ID";
 		}
 
@@ -2117,6 +2124,11 @@ class WP_Query {
 		}
 		$where .= $search . $whichauthor . $whichmimetype;
 
+		// Modify the JOIN clause for attachment searches.
+		if ( $this->is_search && array( 'attachment' ) === (array) $q['post_type'] ) {
+			$join .= " INNER JOIN {$this->db->postmeta} ON ( {$this->db->posts}.ID = {$this->db->postmeta}.post_id )";
+		}
+
 		if ( ! empty( $this->meta_query->queries ) ) {
 			$clauses = $this->meta_query->get_sql( 'post', $this->db->posts, 'ID', $this );
 			$join   .= $clauses['join'];
diff --git tests/phpunit/tests/query/search.php tests/phpunit/tests/query/search.php
index a228f91..15d2193 100644
--- tests/phpunit/tests/query/search.php
+++ tests/phpunit/tests/query/search.php
@@ -280,6 +280,30 @@ class Tests_Query_Search extends WP_UnitTestCase {
 		$this->assertSame( array( $p1, $p3, $p2 ), $q->posts );
 	}
 
+	/**
+	 * @ticket 22744
+	 */
+	public function test_s_should_respect_attachment_file_names() {
+		$attachment = self::factory()->post->create( array(
+			'post_type'    => 'attachment',
+			'post_status'  => 'publish',
+			'post_title'   => 'bar foo',
+			'post_content' => 'foo bar',
+			'post_excerpt' => 'This post has foo',
+		) );
+
+		add_post_meta( $attachment, '_wp_attached_file', 'some-image.png', true );
+
+		$q = new WP_Query( array(
+			's'           => 'image',
+			'fields'      => 'ids',
+			'post_type'   => array( 'attachment' ),
+			'post_status' => 'inherit',
+		) );
+
+		$this->assertSame( array( $attachment ), $q->posts );
+	}
+
 	public function filter_posts_search( $sql ) {
 		return $sql . ' /* posts_search */';
 	}
