Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nested _source retrieval with includes/excludes #33180

Merged
merged 3 commits into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
if (nestedHit) {
value = getNestedSource((Map<String, Object>) value, hitContext);
}

try {
final int initialCapacity = nestedHit ? 1024 : Math.min(1024, source.internalSourceRef().length());
BytesStreamOutput streamOutput = new BytesStreamOutput(initialCapacity);
Expand All @@ -81,6 +82,9 @@ public void hitExecute(SearchContext context, HitContext hitContext) {
private Map<String, Object> getNestedSource(Map<String, Object> sourceAsMap, HitContext hitContext) {
for (SearchHit.NestedIdentity o = hitContext.hit().getNestedIdentity(); o != null; o = o.getChild()) {
sourceAsMap = (Map<String, Object>) sourceAsMap.get(o.getField().string());
if (sourceAsMap == null) {
return null;
}
}
return sourceAsMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -78,6 +79,29 @@ public void testMultipleFiltering() throws IOException {
assertEquals(Collections.singletonMap("field","value"), hitContext.hit().getSourceAsMap());
}

public void testNestedSource() throws IOException {
Map<String, Object> expectedNested = Collections.singletonMap("nested2", Collections.singletonMap("field", "value0"));
XContentBuilder source = XContentFactory.jsonBuilder().startObject()
.field("field", "value")
.field("field2", "value2")
.field("nested1", expectedNested)
.endObject();
FetchSubPhase.HitContext hitContext = hitExecuteMultiple(source, true, null, null,
new SearchHit.NestedIdentity("nested1", 0,null));
assertEquals(expectedNested, hitContext.hit().getSourceAsMap());
hitContext = hitExecuteMultiple(source, true, new String[]{"invalid"}, null,
new SearchHit.NestedIdentity("nested1", 0,null));
assertEquals(Collections.emptyMap(), hitContext.hit().getSourceAsMap());

hitContext = hitExecuteMultiple(source, true, null, null,
new SearchHit.NestedIdentity("nested1", 0, new SearchHit.NestedIdentity("nested2", 0, null)));
assertEquals(Collections.singletonMap("field", "value0"), hitContext.hit().getSourceAsMap());

hitContext = hitExecuteMultiple(source, true, new String[]{"invalid"}, null,
new SearchHit.NestedIdentity("nested1", 0, new SearchHit.NestedIdentity("nested2", 0, null)));
assertEquals(Collections.emptyMap(), hitContext.hit().getSourceAsMap());
}

public void testSourceDisabled() throws IOException {
FetchSubPhase.HitContext hitContext = hitExecute(null, true, null, null);
assertNull(hitContext.hit().getSourceAsMap());
Expand All @@ -96,17 +120,29 @@ public void testSourceDisabled() throws IOException {
}

private FetchSubPhase.HitContext hitExecute(XContentBuilder source, boolean fetchSource, String include, String exclude) {
return hitExecute(source, fetchSource, include, exclude, null);
}


private FetchSubPhase.HitContext hitExecute(XContentBuilder source, boolean fetchSource, String include, String exclude,
SearchHit.NestedIdentity nestedIdentity) {
return hitExecuteMultiple(source, fetchSource,
include == null ? Strings.EMPTY_ARRAY : new String[]{include},
exclude == null ? Strings.EMPTY_ARRAY : new String[]{exclude});
exclude == null ? Strings.EMPTY_ARRAY : new String[]{exclude}, nestedIdentity);
}

private FetchSubPhase.HitContext hitExecuteMultiple(XContentBuilder source, boolean fetchSource, String[] includes, String[] excludes) {
return hitExecuteMultiple(source, fetchSource, includes, excludes, null);
}

private FetchSubPhase.HitContext hitExecuteMultiple(XContentBuilder source, boolean fetchSource, String[] includes, String[] excludes,
SearchHit.NestedIdentity nestedIdentity) {
FetchSourceContext fetchSourceContext = new FetchSourceContext(fetchSource, includes, excludes);
SearchContext searchContext = new FetchSourceSubPhaseTestSearchContext(fetchSourceContext,
source == null ? null : BytesReference.bytes(source));
FetchSubPhase.HitContext hitContext = new FetchSubPhase.HitContext();
hitContext.reset(new SearchHit(1, null, null, null), null, 1, null);
final SearchHit searchHit = new SearchHit(1, null, null, nestedIdentity, null);
hitContext.reset(searchHit, null, 1, null);
FetchSourceSubPhase phase = new FetchSourceSubPhase();
phase.hitExecute(searchContext, hitContext);
return hitContext;
Expand Down