Skip to content

Commit

Permalink
Pass parent filter to inner hit query (opensearch-project#13903) (ope…
Browse files Browse the repository at this point in the history
  • Loading branch information
heemin32 authored May 31, 2024
1 parent 19f860a commit a6c86e7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Fixed
- Fix get field mapping API returns 404 error in mixed cluster with multiple versions ([#13624](https://github.com/opensearch-project/OpenSearch/pull/13624))
- Allow clearing `remote_store.compatibility_mode` setting ([#13646](https://github.com/opensearch-project/OpenSearch/pull/13646))
- Pass parent filter to inner hit query ([#13903](https://github.com/opensearch-project/OpenSearch/pull/13903))

### Security

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,32 @@ protected void doBuild(SearchContext parentSearchContext, InnerHitsContext inner
}
}
String name = innerHitBuilder.getName() != null ? innerHitBuilder.getName() : nestedObjectMapper.fullPath();
ObjectMapper parentObjectMapper = queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
NestedInnerHitSubContext nestedInnerHits = new NestedInnerHitSubContext(
name,
parentSearchContext,
parentObjectMapper,
nestedObjectMapper
);
setupInnerHitsContext(queryShardContext, nestedInnerHits);
queryShardContext.nestedScope().previousLevel();
innerHitsContext.addInnerHitDefinition(nestedInnerHits);
ObjectMapper parentObjectMapper = queryShardContext.nestedScope().getObjectMapper();
BitSetProducer parentFilter;
if (parentObjectMapper == null) {
parentFilter = queryShardContext.bitsetFilter(Queries.newNonNestedFilter());
} else {
parentFilter = queryShardContext.bitsetFilter(parentObjectMapper.nestedTypeFilter());
}
BitSetProducer previousParentFilter = queryShardContext.getParentFilter();
try {
queryShardContext.setParentFilter(parentFilter);
queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
try {
NestedInnerHitSubContext nestedInnerHits = new NestedInnerHitSubContext(
name,
parentSearchContext,
parentObjectMapper,
nestedObjectMapper
);
setupInnerHitsContext(queryShardContext, nestedInnerHits);
innerHitsContext.addInnerHitDefinition(nestedInnerHits);
} finally {
queryShardContext.nestedScope().previousLevel();
}
} finally {
queryShardContext.setParentFilter(previousParentFilter);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,43 @@ public void testInlineLeafInnerHitsNestedQuery() throws Exception {
assertThat(innerHitBuilders.get(leafInnerHits.getName()), Matchers.notNullValue());
}

public void testParentFilterFromInlineLeafInnerHitsNestedQuery() throws Exception {
QueryShardContext queryShardContext = createShardContext();
SearchContext searchContext = mock(SearchContext.class);
when(searchContext.getQueryShardContext()).thenReturn(queryShardContext);

MapperService mapperService = mock(MapperService.class);
IndexSettings settings = new IndexSettings(newIndexMeta("index", Settings.EMPTY), Settings.EMPTY);
when(mapperService.getIndexSettings()).thenReturn(settings);
when(searchContext.mapperService()).thenReturn(mapperService);

InnerHitBuilder leafInnerHits = randomNestedInnerHits();
// Set null for values not related with this test case
leafInnerHits.setScriptFields(null);
leafInnerHits.setHighlightBuilder(null);
leafInnerHits.setSorts(null);

QueryBuilder innerQueryBuilder = spy(new MatchAllQueryBuilder());
when(innerQueryBuilder.toQuery(queryShardContext)).thenAnswer(invoke -> {
QueryShardContext context = invoke.getArgument(0);
if (context.getParentFilter() == null) {
throw new Exception("Expect parent filter to be non-null");
}
return invoke.callRealMethod();
});
NestedQueryBuilder query = new NestedQueryBuilder("nested1", innerQueryBuilder, ScoreMode.None);
query.innerHit(leafInnerHits);
final Map<String, InnerHitContextBuilder> innerHitBuilders = new HashMap<>();
final InnerHitsContext innerHitsContext = new InnerHitsContext();
query.extractInnerHitBuilders(innerHitBuilders);
assertThat(innerHitBuilders.size(), Matchers.equalTo(1));
assertTrue(innerHitBuilders.containsKey(leafInnerHits.getName()));
assertNull(queryShardContext.getParentFilter());
innerHitBuilders.get(leafInnerHits.getName()).build(searchContext, innerHitsContext);
assertNull(queryShardContext.getParentFilter());
verify(innerQueryBuilder).toQuery(queryShardContext);
}

public void testInlineLeafInnerHitsNestedQueryViaBoolQuery() {
InnerHitBuilder leafInnerHits = randomNestedInnerHits();
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("path", new MatchAllQueryBuilder(), ScoreMode.None).innerHit(
Expand Down

0 comments on commit a6c86e7

Please sign in to comment.