diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
index d9d60d2ee9..b9c05eb894 100644
--- src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
+++ src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
@@ -451,7 +451,7 @@ abstract class WP_REST_Controller {
 				continue;
 			}
 
-			if ( ! in_array( $field_name, $requested_fields, true ) ) {
+			if ( ! rest_is_field_included( $field_name, $requested_fields ) ) {
 				continue;
 			}
 
diff --git tests/phpunit/tests/rest-api.php tests/phpunit/tests/rest-api.php
index c0eea9804f..97b79c8c88 100644
--- tests/phpunit/tests/rest-api.php
+++ tests/phpunit/tests/rest-api.php
@@ -560,6 +560,48 @@ class Tests_REST_API extends WP_UnitTestCase {
 		);
 	}
 
+	/**
+	 * Ensure inclusion of deeply nested fields may be controlled with request['_fields'].
+	 *
+	 * @ticket 49648
+	 */
+	public function test_rest_filter_response_fields_deeply_nested_field_filter() {
+		$response = new WP_REST_Response();
+
+		$response->set_data(
+			array(
+				'field' => array(
+					'a' => array(
+						'i'  => 'value i',
+						'ii' => 'value ii',
+					),
+					'b' => array(
+						'iii' => 'value iii',
+						'iv'  => 'value iv',
+					),
+				),
+			)
+		);
+		$request = array(
+			'_fields' => 'field.a.i,field.b.iv',
+		);
+
+		$response = rest_filter_response_fields( $response, null, $request );
+		$this->assertEquals(
+			array(
+				'field' => array(
+					'a' => array(
+						'i' => 'value i',
+					),
+					'b' => array(
+						'iv' => 'value iv',
+					),
+				),
+			),
+			$response->get_data()
+		);
+	}
+
 	/**
 	 * Ensure that specifying a single top-level key in _fields includes that field and all children.
 	 *
diff --git tests/phpunit/tests/rest-api/rest-controller.php tests/phpunit/tests/rest-api/rest-controller.php
index 0fa98078b5..499bc40929 100644
--- tests/phpunit/tests/rest-api/rest-controller.php
+++ tests/phpunit/tests/rest-api/rest-controller.php
@@ -48,6 +48,13 @@ class WP_Test_REST_Controller extends WP_Test_REST_TestCase {
 		);
 	}
 
+	public function tearDown() {
+		parent::tearDown();
+
+		global $wp_rest_additional_fields;
+		$wp_rest_additional_fields = array();
+	}
+
 	public function test_validate_schema_type_integer() {
 
 		$this->assertTrue(
@@ -437,4 +444,125 @@ class WP_Test_REST_Controller extends WP_Test_REST_TestCase {
 
 		$this->assertTrue( $listener->get_call_count( $method ) > $first_call_count );
 	}
+
+	/**
+	 * @dataProvider data_filter_nested_registered_rest_fields
+	 * @ticket 49648
+	 */
+	public function test_filter_nested_registered_rest_fields( $filter, $expected ) {
+		$controller = new WP_REST_Test_Controller();
+
+		register_rest_field(
+			'type',
+			'field',
+			array(
+				'schema'       => array(
+					'type'        => 'object',
+					'description' => 'A complex object',
+					'context'     => array( 'view', 'edit' ),
+					'properties'  => array(
+						'a' => array(
+							'i'  => 'string',
+							'ii' => 'string',
+						),
+						'b' => array(
+							'iii' => 'string',
+							'iv'  => 'string',
+						),
+					),
+				),
+				'get_callback' => array( $this, 'register_nested_rest_field_get_callback' ),
+			)
+		);
+
+		$request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
+		$request->set_param( '_fields', $filter );
+
+		$response = $controller->prepare_item_for_response( array(), $request );
+		$response = rest_filter_response_fields( $response, rest_get_server(), $request );
+
+		$this->assertEquals( $expected, $response->get_data() );
+	}
+
+	public function register_nested_rest_field_get_callback() {
+		return array(
+			'a' => array(
+				'i'  => 'value i',
+				'ii' => 'value ii',
+			),
+			'b' => array(
+				'iii' => 'value iii',
+				'iv'  => 'value iv',
+			),
+		);
+	}
+
+	public function data_filter_nested_registered_rest_fields() {
+		return array(
+			array(
+				'field',
+				array(
+					'field' => array(
+						'a' => array(
+							'i'  => 'value i',
+							'ii' => 'value ii',
+						),
+						'b' => array(
+							'iii' => 'value iii',
+							'iv'  => 'value iv',
+						),
+					),
+				),
+			),
+			array(
+				'field.a',
+				array(
+					'field' => array(
+						'a' => array(
+							'i'  => 'value i',
+							'ii' => 'value ii',
+						),
+					),
+				),
+			),
+			array(
+				'field.b',
+				array(
+					'field' => array(
+						'b' => array(
+							'iii' => 'value iii',
+							'iv'  => 'value iv',
+						),
+					),
+				),
+			),
+			array(
+				'field.a.i,field.b.iv',
+				array(
+					'field' => array(
+						'a' => array(
+							'i' => 'value i',
+						),
+						'b' => array(
+							'iv' => 'value iv',
+						),
+					),
+				),
+			),
+			array(
+				'field.a,field.b.iii',
+				array(
+					'field' => array(
+						'a' => array(
+							'i'  => 'value i',
+							'ii' => 'value ii',
+						),
+						'b' => array(
+							'iii' => 'value iii',
+						),
+					),
+				),
+			),
+		);
+	}
 }
