Skip to content

Commit db5240e

Browse files
authored
Pass parent filter to inner hit query (opensearch-project#13770)
Signed-off-by: Heemin Kim <heemin@amazon.com>
1 parent 2fd2c34 commit db5240e

File tree

3 files changed

+62
-10
lines changed

3 files changed

+62
-10
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4545
- Fix get field mapping API returns 404 error in mixed cluster with multiple versions ([#13624](https://github.com/opensearch-project/OpenSearch/pull/13624))
4646
- Allow clearing `remote_store.compatibility_mode` setting ([#13646](https://github.com/opensearch-project/OpenSearch/pull/13646))
4747
- Fix ReplicaShardBatchAllocator to batch shards without duplicates ([#13710](https://github.com/opensearch-project/OpenSearch/pull/13710))
48+
- Pass parent filter to inner hit query ([#13770](https://github.com/opensearch-project/OpenSearch/pull/13770))
4849

4950
### Security
5051

server/src/main/java/org/opensearch/index/query/NestedQueryBuilder.java

+26-10
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,32 @@ protected void doBuild(SearchContext parentSearchContext, InnerHitsContext inner
401401
}
402402
}
403403
String name = innerHitBuilder.getName() != null ? innerHitBuilder.getName() : nestedObjectMapper.fullPath();
404-
ObjectMapper parentObjectMapper = queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
405-
NestedInnerHitSubContext nestedInnerHits = new NestedInnerHitSubContext(
406-
name,
407-
parentSearchContext,
408-
parentObjectMapper,
409-
nestedObjectMapper
410-
);
411-
setupInnerHitsContext(queryShardContext, nestedInnerHits);
412-
queryShardContext.nestedScope().previousLevel();
413-
innerHitsContext.addInnerHitDefinition(nestedInnerHits);
404+
ObjectMapper parentObjectMapper = queryShardContext.nestedScope().getObjectMapper();
405+
BitSetProducer parentFilter;
406+
if (parentObjectMapper == null) {
407+
parentFilter = queryShardContext.bitsetFilter(Queries.newNonNestedFilter());
408+
} else {
409+
parentFilter = queryShardContext.bitsetFilter(parentObjectMapper.nestedTypeFilter());
410+
}
411+
BitSetProducer previousParentFilter = queryShardContext.getParentFilter();
412+
try {
413+
queryShardContext.setParentFilter(parentFilter);
414+
queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
415+
try {
416+
NestedInnerHitSubContext nestedInnerHits = new NestedInnerHitSubContext(
417+
name,
418+
parentSearchContext,
419+
parentObjectMapper,
420+
nestedObjectMapper
421+
);
422+
setupInnerHitsContext(queryShardContext, nestedInnerHits);
423+
innerHitsContext.addInnerHitDefinition(nestedInnerHits);
424+
} finally {
425+
queryShardContext.nestedScope().previousLevel();
426+
}
427+
} finally {
428+
queryShardContext.setParentFilter(previousParentFilter);
429+
}
414430
}
415431
}
416432

server/src/test/java/org/opensearch/index/query/NestedQueryBuilderTests.java

+35
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,41 @@ public void testInlineLeafInnerHitsNestedQuery() throws Exception {
311311
assertThat(innerHitBuilders.get(leafInnerHits.getName()), Matchers.notNullValue());
312312
}
313313

314+
public void testParentFilterFromInlineLeafInnerHitsNestedQuery() throws Exception {
315+
QueryShardContext queryShardContext = createShardContext();
316+
SearchContext searchContext = mock(SearchContext.class);
317+
when(searchContext.getQueryShardContext()).thenReturn(queryShardContext);
318+
319+
MapperService mapperService = mock(MapperService.class);
320+
IndexSettings settings = new IndexSettings(newIndexMeta("index", Settings.EMPTY), Settings.EMPTY);
321+
when(mapperService.getIndexSettings()).thenReturn(settings);
322+
when(searchContext.mapperService()).thenReturn(mapperService);
323+
324+
InnerHitBuilder leafInnerHits = randomNestedInnerHits();
325+
leafInnerHits.setScriptFields(null);
326+
leafInnerHits.setHighlightBuilder(null);
327+
328+
QueryBuilder innerQueryBuilder = spy(new MatchAllQueryBuilder());
329+
when(innerQueryBuilder.toQuery(queryShardContext)).thenAnswer(invoke -> {
330+
QueryShardContext context = invoke.getArgument(0);
331+
if (context.getParentFilter() == null) {
332+
throw new Exception("Expect parent filter to be non-null");
333+
}
334+
return invoke.callRealMethod();
335+
});
336+
NestedQueryBuilder query = new NestedQueryBuilder("nested1", innerQueryBuilder, ScoreMode.None);
337+
query.innerHit(leafInnerHits);
338+
final Map<String, InnerHitContextBuilder> innerHitBuilders = new HashMap<>();
339+
final InnerHitsContext innerHitsContext = new InnerHitsContext();
340+
query.extractInnerHitBuilders(innerHitBuilders);
341+
assertThat(innerHitBuilders.size(), Matchers.equalTo(1));
342+
assertTrue(innerHitBuilders.containsKey(leafInnerHits.getName()));
343+
assertNull(queryShardContext.getParentFilter());
344+
innerHitBuilders.get(leafInnerHits.getName()).build(searchContext, innerHitsContext);
345+
assertNull(queryShardContext.getParentFilter());
346+
verify(innerQueryBuilder).toQuery(queryShardContext);
347+
}
348+
314349
public void testInlineLeafInnerHitsNestedQueryViaBoolQuery() {
315350
InnerHitBuilder leafInnerHits = randomNestedInnerHits();
316351
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("path", new MatchAllQueryBuilder(), ScoreMode.None).innerHit(

0 commit comments

Comments
 (0)