The `nested` aggregator should also resolve and use the parentFilter of the closest `reverse_nested` aggregator.
Closes #6994 Closes #7048
This commit is contained in:
parent
96ecec34d1
commit
2e9ee5c937
|
@ -71,16 +71,13 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||||
@Override
|
@Override
|
||||||
public void setNextReader(AtomicReaderContext reader) {
|
public void setNextReader(AtomicReaderContext reader) {
|
||||||
if (parentFilter == null) {
|
if (parentFilter == null) {
|
||||||
NestedAggregator closestNestedAggregator = findClosestNestedAggregator(parentAggregator);
|
|
||||||
final Filter parentFilterNotCached;
|
|
||||||
if (closestNestedAggregator == null) {
|
|
||||||
parentFilterNotCached = NonNestedDocsFilter.INSTANCE;
|
|
||||||
} else {
|
|
||||||
// The aggs are instantiated in reverse, first the most inner nested aggs and lastly the top level aggs
|
// The aggs are instantiated in reverse, first the most inner nested aggs and lastly the top level aggs
|
||||||
// So at the time a nested 'nested' aggs is parsed its closest parent nested aggs hasn't been constructed.
|
// So at the time a nested 'nested' aggs is parsed its closest parent nested aggs hasn't been constructed.
|
||||||
// So the trick to set at the last moment just before needed and we can use its child filter as the
|
// So the trick to set at the last moment just before needed and we can use its child filter as the
|
||||||
// parent filter.
|
// parent filter.
|
||||||
parentFilterNotCached = closestNestedAggregator.childFilter;
|
Filter parentFilterNotCached = findClosestNestedPath(parentAggregator);
|
||||||
|
if (parentFilterNotCached == null) {
|
||||||
|
parentFilterNotCached = NonNestedDocsFilter.INSTANCE;
|
||||||
}
|
}
|
||||||
parentFilter = SearchContext.current().filterCache().cache(parentFilterNotCached);
|
parentFilter = SearchContext.current().filterCache().cache(parentFilterNotCached);
|
||||||
// if the filter cache is disabled, we still need to produce bit sets
|
// if the filter cache is disabled, we still need to produce bit sets
|
||||||
|
@ -103,10 +100,8 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collect(int parentDoc, long bucketOrd) throws IOException {
|
public void collect(int parentDoc, long bucketOrd) throws IOException {
|
||||||
|
|
||||||
// here we translate the parent doc to a list of its nested docs, and then call super.collect for evey one of them
|
// here we translate the parent doc to a list of its nested docs, and then call super.collect for evey one of them
|
||||||
// so they'll be collected
|
// so they'll be collected
|
||||||
|
|
||||||
if (parentDoc == 0 || parentDocs == null) {
|
if (parentDoc == 0 || parentDocs == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -135,10 +130,12 @@ public class NestedAggregator extends SingleBucketAggregator implements ReaderCo
|
||||||
return nestedPath;
|
return nestedPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NestedAggregator findClosestNestedAggregator(Aggregator parent) {
|
private static Filter findClosestNestedPath(Aggregator parent) {
|
||||||
for (; parent != null; parent = parent.parent()) {
|
for (; parent != null; parent = parent.parent()) {
|
||||||
if (parent instanceof NestedAggregator) {
|
if (parent instanceof NestedAggregator) {
|
||||||
return (NestedAggregator) parent;
|
return ((NestedAggregator) parent).childFilter;
|
||||||
|
} else if (parent instanceof ReverseNestedAggregator) {
|
||||||
|
return ((ReverseNestedAggregator) parent).getParentFilter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -38,8 +38,6 @@ import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.search.aggregations.bucket.nested.NestedAggregator.findClosestNestedAggregator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -128,6 +126,14 @@ public class ReverseNestedAggregator extends SingleBucketAggregator implements R
|
||||||
collectBucket(parentDoc, bucketOrd);
|
collectBucket(parentDoc, bucketOrd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static NestedAggregator findClosestNestedAggregator(Aggregator parent) {
|
||||||
|
for (; parent != null; parent = parent.parent()) {
|
||||||
|
if (parent instanceof NestedAggregator) {
|
||||||
|
return (NestedAggregator) parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InternalAggregation buildAggregation(long owningBucketOrdinal) {
|
public InternalAggregation buildAggregation(long owningBucketOrdinal) {
|
||||||
|
@ -139,6 +145,10 @@ public class ReverseNestedAggregator extends SingleBucketAggregator implements R
|
||||||
return new InternalReverseNested(name, 0, buildEmptySubAggregations());
|
return new InternalReverseNested(name, 0, buildEmptySubAggregations());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Filter getParentFilter() {
|
||||||
|
return parentFilter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doClose() {
|
protected void doClose() {
|
||||||
Releasables.close(bucketOrdToLastCollectedParentDocRecycler);
|
Releasables.close(bucketOrdToLastCollectedParentDocRecycler);
|
||||||
|
|
|
@ -129,6 +129,29 @@ public class ReverseNestedTests extends ElasticsearchIntegrationTest {
|
||||||
verifyResults(response);
|
verifyResults(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simple_nested1ToRootToNested2() throws Exception {
|
||||||
|
SearchResponse response = client().prepareSearch("idx").setTypes("type2")
|
||||||
|
.addAggregation(nested("nested1").path("nested1")
|
||||||
|
.subAggregation(
|
||||||
|
reverseNested("nested1_to_root")
|
||||||
|
.subAggregation(nested("root_to_nested2").path("nested1.nested2"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.get();
|
||||||
|
|
||||||
|
assertSearchResponse(response);
|
||||||
|
Nested nested = response.getAggregations().get("nested1");
|
||||||
|
assertThat(nested.getName(), equalTo("nested1"));
|
||||||
|
assertThat(nested.getDocCount(), equalTo(9l));
|
||||||
|
ReverseNested reverseNested = nested.getAggregations().get("nested1_to_root");
|
||||||
|
assertThat(reverseNested.getName(), equalTo("nested1_to_root"));
|
||||||
|
assertThat(reverseNested.getDocCount(), equalTo(9l));
|
||||||
|
nested = reverseNested.getAggregations().get("root_to_nested2");
|
||||||
|
assertThat(nested.getName(), equalTo("root_to_nested2"));
|
||||||
|
assertThat(nested.getDocCount(), equalTo(25l));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void simple_reverseNestedToNested1() throws Exception {
|
public void simple_reverseNestedToNested1() throws Exception {
|
||||||
SearchResponse response = client().prepareSearch("idx")
|
SearchResponse response = client().prepareSearch("idx")
|
||||||
|
|
Loading…
Reference in New Issue