@@ -117,25 +117,38 @@ module SchemaDefinition
117117 } )
118118 end
119119
120- it "uses `name_in_index` in `_source.excludes` for `returnable: false` fields" do
120+ it "uses `name_in_index` in `_source.excludes` for non-highlightable `returnable: false` fields" do
121121 mapping = index_mapping_for "my_type" do |s |
122122 s . object_type "MyType" do |t |
123123 t . field "id" , "ID"
124- t . field "name" , "String"
125- t . field "internal_code_gql" , "String" , name_in_index : "internal_code" , returnable : false
124+ t . field "internal_count_gql" , "Int" , name_in_index : "internal_count" , returnable : false
126125 t . index "my_type"
127126 end
128127 end
129128
130- expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "internal_code " )
129+ expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "internal_count " )
131130 # The field should still appear in properties (it's indexed, just not in _source)
131+ expect ( mapping . dig ( "properties" , "internal_count" ) ) . to eq ( { "type" => "integer" } )
132+ end
133+
134+ it "keeps highlightable `returnable: false` fields in `_source` so they can still be highlighted" do
135+ mapping = index_mapping_for "my_type" do |s |
136+ s . object_type "MyType" do |t |
137+ t . field "id" , "ID"
138+ t . field "internal_code" , "String" , returnable : false
139+ t . index "my_type"
140+ end
141+ end
142+
143+ expect ( mapping ) . not_to have_key ( "_source" )
132144 expect ( mapping . dig ( "properties" , "internal_code" ) ) . to eq ( { "type" => "keyword" } )
133145 end
134146
135- it "includes `.*` in `_source.excludes` for `returnable: false` object fields" do
147+ it "only excludes non-highlightable descendants for implicitly highlightable `returnable: false` object fields" do
136148 mapping = index_mapping_for "my_type" do |s |
137149 s . object_type "InternalMetadata" do |t |
138150 t . field "internal_code" , "String"
151+ t . field "internal_count" , "Int"
139152 end
140153
141154 s . object_type "MyType" do |t |
@@ -145,33 +158,55 @@ module SchemaDefinition
145158 end
146159 end
147160
161+ expect ( mapping ) . to include ( "_source" => { "excludes" => [ "internal_metadata.internal_count" ] } )
162+ expect ( mapping . dig ( "properties" , "internal_metadata" , "properties" , "internal_code" ) ) . to eq ( { "type" => "keyword" } )
163+ expect ( mapping . dig ( "properties" , "internal_metadata" , "properties" , "internal_count" ) ) . to eq ( { "type" => "integer" } )
164+ end
165+
166+ it "excludes all descendants for explicitly non-highlightable `returnable: false` object fields even when a child field is highlightable" do
167+ mapping = index_mapping_for "my_type" do |s |
168+ s . object_type "InternalMetadata" do |t |
169+ t . field "internal_code" , "String" , highlightable : true
170+ t . field "internal_count" , "Int"
171+ end
172+
173+ s . object_type "MyType" do |t |
174+ t . field "id" , "ID"
175+ t . field "internal_metadata" , "InternalMetadata" , returnable : false , highlightable : false
176+ t . index "my_type"
177+ end
178+ end
179+
148180 expect ( mapping ) . to include ( "_source" => { "excludes" => [ "internal_metadata.*" ] } )
149181 expect ( mapping . dig ( "properties" , "internal_metadata" , "properties" , "internal_code" ) ) . to eq ( { "type" => "keyword" } )
182+ expect ( mapping . dig ( "properties" , "internal_metadata" , "properties" , "internal_count" ) ) . to eq ( { "type" => "integer" } )
150183 end
151184
152- it "excludes `returnable: false` indexing-only fields but not `graphql_only` fields" do
185+ it "excludes non-highlightable `returnable: false` indexing-only fields but not `graphql_only` fields" do
153186 mapping = index_mapping_for "my_type" do |s |
154187 s . object_type "MyType" do |t |
155188 t . field "id" , "ID"
156189 t . field "name" , "String"
157- t . field "legacy_name" , "String" , graphql_only : true , name_in_index : "name" , returnable : false
158- t . field "internal_code" , "String" , indexing_only : true , returnable : false
190+ t . field "count" , "Int"
191+ t . field "legacy_count" , "Int" , graphql_only : true , name_in_index : "count" , returnable : false
192+ t . field "internal_count" , "Int" , indexing_only : true , returnable : false
159193 t . index "my_type"
160194 end
161195 end
162196
163- expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "internal_code " )
197+ expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "internal_count " )
164198 expect ( mapping . fetch ( "properties" ) ) . to include (
165199 "name" => { "type" => "keyword" } ,
166- "internal_code" => { "type" => "keyword" }
200+ "count" => { "type" => "integer" } ,
201+ "internal_count" => { "type" => "integer" }
167202 )
168- expect ( mapping . fetch ( "properties" ) ) . not_to include ( "legacy_name " )
203+ expect ( mapping . fetch ( "properties" ) ) . not_to include ( "legacy_count " )
169204 end
170205
171206 it "uses full indexed paths in `_source.excludes` for `returnable: false` fields under nested mappings" do
172207 mapping = index_mapping_for "my_type" do |s |
173208 s . object_type "Parent" do |t |
174- t . field "child " , "String " , name_in_index : "child_in_index " , returnable : false
209+ t . field "child_count_gql " , "Int " , name_in_index : "child_count " , returnable : false
175210 end
176211
177212 s . object_type "Grandparent" do |t |
@@ -187,19 +222,35 @@ module SchemaDefinition
187222 end
188223 end
189224
190- expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "grandparents_in_index.parent_in_index.child_in_index " )
225+ expect ( mapping . dig ( "_source" , "excludes" ) ) . to contain_exactly ( "grandparents_in_index.parent_in_index.child_count " )
191226 expect ( mapping . dig ( "properties" , "grandparents_in_index" ) ) . to include (
192227 "type" => "nested" ,
193228 "properties" => {
194229 "parent_in_index" => {
195230 "properties" => {
196- "child_in_index " => { "type" => "keyword " }
231+ "child_count " => { "type" => "integer " }
197232 }
198233 }
199234 }
200235 )
201236 end
202237
238+ it "excludes all descendants for non-highlightable `returnable: false` object fields" do
239+ mapping = index_mapping_for "my_type" do |s |
240+ s . object_type "InternalMetrics" do |t |
241+ t . field "count" , "Int"
242+ end
243+
244+ s . object_type "MyType" do |t |
245+ t . field "id" , "ID"
246+ t . field "internal_metrics" , "InternalMetrics" , returnable : false
247+ t . index "my_type"
248+ end
249+ end
250+
251+ expect ( mapping ) . to include ( "_source" => { "excludes" => [ "internal_metrics.*" ] } )
252+ expect ( mapping . dig ( "properties" , "internal_metrics" , "properties" , "count" ) ) . to eq ( { "type" => "integer" } )
253+ end
203254 it "does not include `_source` config when all fields are returnable" do
204255 mapping = index_mapping_for "my_type" do |s |
205256 s . object_type "MyType" do |t |
0 commit comments