I've added a basic test program below which reproduces this.
The Parent and Child documents are very basic, both having just a simple Title text field, with the child document having the parent set as the parent (routing etc. is all configured correctly).
Running the test returns the following:
Parent1 [ID]
[UqLUWssUTcqaQsYRhdjSVA][test-index][0] [Shard]
Parent2 [ID]
[UqLUWssUTcqaQsYRhdjSVA][test-index][0] [Shard]
Parent1 [ID]
[UqLUWssUTcqaQsYRhdjSVA][test-index][0] [Shard]
Parent2 [ID]
null [Shard]
As you can see, the second document returns a null shard value when an inner hit is being used in the search. I could understand if it was the inner hit that didn't have a shard set, however this is a document of the result type, which has a shard set if inner hits aren't used (the size of the result doesn't make a difference, the shard is only ever being set on the first document in the SearchHits).
package com.main.elasticsearch;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.support.QueryInnerHitBuilder;
import org.elasticsearch.search.SearchHit;
public class ElasticInnerHitsTest {
public static void main(String[] args) {
Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", "testcluster").build();
Client client = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("localhost", 9300));
BoolQueryBuilder query = QueryBuilders.boolQuery().must(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
FilterBuilders.hasChildFilter("Child", QueryBuilders.matchAllQuery())));
SearchResponse response = client.prepareSearch("test-index")
.setTypes("Parent")
.setQuery(query)
.setFrom(0)
.setSize(2)
.execute()
.actionGet();
for (SearchHit hit : response.getHits()) {
System.out.println(hit.getId());
System.out.println(hit.getShard());
}
QueryInnerHitBuilder innerHit = new QueryInnerHitBuilder();
BoolQueryBuilder innerQuery = QueryBuilders.boolQuery().must(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
FilterBuilders.hasChildFilter("Child", QueryBuilders.matchAllQuery())
.innerHit(innerHit)));
response = client.prepareSearch("test-index")
.setTypes("Parent")
.setQuery(innerQuery)
.setFrom(0)
.setSize(2)
.execute()
.actionGet();
for (SearchHit hit : response.getHits()) {
System.out.println(hit.getId());
System.out.println(hit.getShard());
}
client.close();
}
}