diff --git a/build.gradle b/build.gradle
index 09748ea1e8a..31784a1798a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -138,6 +138,7 @@ subprojects {
"org.elasticsearch.plugin:transport-netty4-client:${version}": ':modules:transport-netty4',
"org.elasticsearch.plugin:reindex-client:${version}": ':modules:reindex',
"org.elasticsearch.plugin:lang-mustache-client:${version}": ':modules:lang-mustache',
+ "org.elasticsearch.plugin:parent-join-client:${version}": ':modules:parent-join',
"org.elasticsearch.plugin:percolator-client:${version}": ':modules:percolator',
]
project.afterEvaluate {
diff --git a/buildSrc/src/main/resources/checkstyle_suppressions.xml b/buildSrc/src/main/resources/checkstyle_suppressions.xml
index 9a550740fde..4acd927fff1 100644
--- a/buildSrc/src/main/resources/checkstyle_suppressions.xml
+++ b/buildSrc/src/main/resources/checkstyle_suppressions.xml
@@ -620,7 +620,6 @@
-
@@ -689,7 +688,6 @@
-
@@ -716,7 +714,6 @@
-
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/QueryDSLDocumentationTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/QueryDSLDocumentationTests.java
index f01e4824b3f..f48572b0473 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/QueryDSLDocumentationTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/QueryDSLDocumentationTests.java
@@ -51,8 +51,6 @@ import static org.elasticsearch.index.query.QueryBuilders.geoBoundingBoxQuery;
import static org.elasticsearch.index.query.QueryBuilders.geoDistanceQuery;
import static org.elasticsearch.index.query.QueryBuilders.geoPolygonQuery;
import static org.elasticsearch.index.query.QueryBuilders.geoShapeQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.QueryBuilders.idsQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
@@ -216,24 +214,6 @@ public class QueryDSLDocumentationTests extends ESTestCase {
}
}
- public void testHasChild() {
- // tag::has_child
- hasChildQuery(
- "blog_tag", // <1>
- termQuery("tag","something"), // <2>
- ScoreMode.None); // <3>
- // end::has_child
- }
-
- public void testHasParent() {
- // tag::has_parent
- hasParentQuery(
- "blog", // <1>
- termQuery("tag","something"), // <2>
- false); // <3>
- // end::has_parent
- }
-
public void testIds() {
// tag::ids
idsQuery("my_type", "type2")
diff --git a/client/transport/build.gradle b/client/transport/build.gradle
index 77833c1f267..b2edc9c8fcd 100644
--- a/client/transport/build.gradle
+++ b/client/transport/build.gradle
@@ -31,6 +31,7 @@ dependencies {
compile "org.elasticsearch.plugin:reindex-client:${version}"
compile "org.elasticsearch.plugin:lang-mustache-client:${version}"
compile "org.elasticsearch.plugin:percolator-client:${version}"
+ compile "org.elasticsearch.plugin:parent-join-client:${version}"
testCompile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
testCompile "junit:junit:${versions.junit}"
testCompile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
diff --git a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
index dd23429dbdb..b6eb84b03b7 100644
--- a/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
@@ -195,7 +195,8 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
}
}
- InnerHitBuilder(InnerHitBuilder other, QueryBuilder query, String parentChildType, boolean ignoreUnmapped) {
+ // NORELEASE Do not use this ctr, it is public for hasChild and hasParent query but this is temporary
+ public InnerHitBuilder(InnerHitBuilder other, QueryBuilder query, String parentChildType, boolean ignoreUnmapped) {
this(other);
this.query = query;
this.parentChildType = parentChildType;
@@ -751,7 +752,8 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
}
}
- static InnerHitBuilder rewrite(InnerHitBuilder original, QueryBuilder rewrittenQuery) {
+ // TODO public for hasParent and hasChild query
+ public static InnerHitBuilder rewrite(InnerHitBuilder original, QueryBuilder rewrittenQuery) {
if (original == null) {
return null;
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
index b0c49a3f4a8..2d23f256f06 100644
--- a/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/NestedQueryBuilder.java
@@ -23,7 +23,6 @@ import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.search.join.ScoreMode;
-import org.apache.lucene.search.join.ToParentBlockJoinQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
@@ -36,6 +35,7 @@ import org.elasticsearch.index.search.ESToParentBlockJoinQuery;
import org.elasticsearch.index.search.NestedHelper;
import java.io.IOException;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -144,7 +144,7 @@ public class NestedQueryBuilder extends AbstractQueryBuilder
builder.field(PATH_FIELD.getPreferredName(), path);
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
if (scoreMode != null) {
- builder.field(SCORE_MODE_FIELD.getPreferredName(), HasChildQueryBuilder.scoreModeAsString(scoreMode));
+ builder.field(SCORE_MODE_FIELD.getPreferredName(), scoreModeAsString(scoreMode));
}
printBoostAndQueryName(builder);
if (innerHitBuilder != null) {
@@ -183,7 +183,7 @@ public class NestedQueryBuilder extends AbstractQueryBuilder
} else if (IGNORE_UNMAPPED_FIELD.match(currentFieldName)) {
ignoreUnmapped = parser.booleanValue();
} else if (SCORE_MODE_FIELD.match(currentFieldName)) {
- scoreMode = HasChildQueryBuilder.parseScoreMode(parser.text());
+ scoreMode = parseScoreMode(parser.text());
} else if (AbstractQueryBuilder.NAME_FIELD.match(currentFieldName)) {
queryName = parser.text();
} else {
@@ -201,6 +201,30 @@ public class NestedQueryBuilder extends AbstractQueryBuilder
return queryBuilder;
}
+ public static ScoreMode parseScoreMode(String scoreModeString) {
+ if ("none".equals(scoreModeString)) {
+ return ScoreMode.None;
+ } else if ("min".equals(scoreModeString)) {
+ return ScoreMode.Min;
+ } else if ("max".equals(scoreModeString)) {
+ return ScoreMode.Max;
+ } else if ("avg".equals(scoreModeString)) {
+ return ScoreMode.Avg;
+ } else if ("sum".equals(scoreModeString)) {
+ return ScoreMode.Total;
+ }
+ throw new IllegalArgumentException("No score mode for child query [" + scoreModeString + "] found");
+ }
+
+ public static String scoreModeAsString(ScoreMode scoreMode) {
+ if (scoreMode == ScoreMode.Total) {
+ // Lucene uses 'total' but 'sum' is more consistent with other elasticsearch APIs
+ return "sum";
+ } else {
+ return scoreMode.name().toLowerCase(Locale.ROOT);
+ }
+ }
+
@Override
public final String getWriteableName() {
return NAME;
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java b/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
index 805ec5fa782..df0493d61c8 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
@@ -471,30 +471,6 @@ public abstract class QueryBuilders {
return moreLikeThisQuery(null, null, likeItems);
}
- /**
- * Constructs a new has_child query, with the child type and the query to run on the child documents. The
- * results of this query are the parent docs that those child docs matched.
- *
- * @param type The child type.
- * @param query The query.
- * @param scoreMode How the scores from the children hits should be aggregated into the parent hit.
- */
- public static HasChildQueryBuilder hasChildQuery(String type, QueryBuilder query, ScoreMode scoreMode) {
- return new HasChildQueryBuilder(type, query, scoreMode);
- }
-
- /**
- * Constructs a new parent query, with the parent type and the query to run on the parent documents. The
- * results of this query are the children docs that those parent docs matched.
- *
- * @param type The parent type.
- * @param query The query.
- * @param score Whether the score from the parent hit should propagate to the child hit
- */
- public static HasParentQueryBuilder hasParentQuery(String type, QueryBuilder query, boolean score) {
- return new HasParentQueryBuilder(type, query, score);
- }
-
/**
* Constructs a new parent id query that returns all child documents of the specified type that
* point to the specified id.
diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java
index 8707d851d3a..85308f0c249 100644
--- a/core/src/main/java/org/elasticsearch/search/SearchModule.java
+++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java
@@ -20,8 +20,6 @@
package org.elasticsearch.search;
import org.apache.lucene.search.BooleanQuery;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.NamedRegistry;
import org.elasticsearch.common.geo.ShapesAvailability;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
@@ -45,8 +43,6 @@ import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.GeoPolygonQueryBuilder;
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
-import org.elasticsearch.index.query.HasChildQueryBuilder;
-import org.elasticsearch.index.query.HasParentQueryBuilder;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
@@ -103,8 +99,6 @@ import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.adjacency.AdjacencyMatrixAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.adjacency.InternalAdjacencyMatrix;
-import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
-import org.elasticsearch.search.aggregations.bucket.children.InternalChildren;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregationBuilder;
@@ -256,7 +250,6 @@ import org.elasticsearch.search.suggest.term.TermSuggestionBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -410,9 +403,6 @@ public class SearchModule {
GeoCentroidAggregationBuilder::parse).addResultReader(InternalGeoCentroid::new));
registerAggregation(new AggregationSpec(ScriptedMetricAggregationBuilder.NAME, ScriptedMetricAggregationBuilder::new,
ScriptedMetricAggregationBuilder::parse).addResultReader(InternalScriptedMetric::new));
- registerAggregation(new AggregationSpec(ChildrenAggregationBuilder.NAME, ChildrenAggregationBuilder::new,
- ChildrenAggregationBuilder::parse).addResultReader(InternalChildren::new));
-
registerFromPlugin(plugins, SearchPlugin::getAggregations, this::registerAggregation);
}
@@ -706,8 +696,6 @@ public class SearchModule {
MatchPhrasePrefixQueryBuilder::fromXContent));
registerQuery(new QuerySpec<>(MultiMatchQueryBuilder.NAME, MultiMatchQueryBuilder::new, MultiMatchQueryBuilder::fromXContent));
registerQuery(new QuerySpec<>(NestedQueryBuilder.NAME, NestedQueryBuilder::new, NestedQueryBuilder::fromXContent));
- registerQuery(new QuerySpec<>(HasChildQueryBuilder.NAME, HasChildQueryBuilder::new, HasChildQueryBuilder::fromXContent));
- registerQuery(new QuerySpec<>(HasParentQueryBuilder.NAME, HasParentQueryBuilder::new, HasParentQueryBuilder::fromXContent));
registerQuery(new QuerySpec<>(DisMaxQueryBuilder.NAME, DisMaxQueryBuilder::new, DisMaxQueryBuilder::fromXContent));
registerQuery(new QuerySpec<>(IdsQueryBuilder.NAME, IdsQueryBuilder::new, IdsQueryBuilder::fromXContent));
registerQuery(new QuerySpec<>(MatchAllQueryBuilder.NAME, MatchAllQueryBuilder::new, MatchAllQueryBuilder::fromXContent));
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java
index f43c2670abd..8b704ee8a69 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java
+++ b/core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java
@@ -23,8 +23,6 @@ import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.bucket.adjacency.AdjacencyMatrix;
import org.elasticsearch.search.aggregations.bucket.adjacency.AdjacencyMatrixAggregationBuilder;
-import org.elasticsearch.search.aggregations.bucket.children.Children;
-import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filters.Filters;
@@ -163,20 +161,20 @@ public class AggregationBuilders {
public static FiltersAggregationBuilder filters(String name, QueryBuilder... filters) {
return new FiltersAggregationBuilder(name, filters);
}
-
+
/**
* Create a new {@link AdjacencyMatrix} aggregation with the given name.
*/
public static AdjacencyMatrixAggregationBuilder adjacencyMatrix(String name, Map filters) {
return new AdjacencyMatrixAggregationBuilder(name, filters);
- }
-
+ }
+
/**
* Create a new {@link AdjacencyMatrix} aggregation with the given name and separator
*/
public static AdjacencyMatrixAggregationBuilder adjacencyMatrix(String name, String separator, Map filters) {
return new AdjacencyMatrixAggregationBuilder(name, separator, filters);
- }
+ }
/**
* Create a new {@link Sampler} aggregation with the given name.
@@ -220,13 +218,6 @@ public class AggregationBuilders {
return new ReverseNestedAggregationBuilder(name);
}
- /**
- * Create a new {@link Children} aggregation with the given name.
- */
- public static ChildrenAggregationBuilder children(String name, String childType) {
- return new ChildrenAggregationBuilder(name, childType);
- }
-
/**
* Create a new {@link GeoDistance} aggregation with the given name.
*/
diff --git a/core/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/CustomQueryScorer.java b/core/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/CustomQueryScorer.java
index e25e7b74941..2f728e21b6f 100644
--- a/core/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/CustomQueryScorer.java
+++ b/core/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/CustomQueryScorer.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.highlight.WeightedSpanTerm;
import org.apache.lucene.search.highlight.WeightedSpanTermExtractor;
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
-import org.elasticsearch.index.query.HasChildQueryBuilder;
import java.io.IOException;
import java.util.Map;
@@ -83,7 +82,7 @@ public final class CustomQueryScorer extends QueryScorer {
}
protected void extract(Query query, float boost, Map terms) throws IOException {
- if (query instanceof HasChildQueryBuilder.LateParsingQuery) {
+ if (isChildOrParentQuery(query.getClass())) {
// skip has_child or has_parent queries, see: https://github.com/elastic/elasticsearch/issues/14999
return;
} else if (query instanceof FunctionScoreQuery) {
@@ -94,5 +93,13 @@ public final class CustomQueryScorer extends QueryScorer {
super.extract(query, boost, terms);
}
}
+
+ /**
+ * Workaround to detect parent/child query
+ */
+ private static final String PARENT_CHILD_QUERY_NAME = "HasChildQueryBuilder$LateParsingQuery";
+ private static boolean isChildOrParentQuery(Class> clazz) {
+ return clazz.getName().endsWith(PARENT_CHILD_QUERY_NAME);
+ }
}
}
diff --git a/core/src/test/java/org/elasticsearch/action/bulk/BulkWithUpdatesIT.java b/core/src/test/java/org/elasticsearch/action/bulk/BulkWithUpdatesIT.java
index 21930b3763b..cf41042ab8c 100644
--- a/core/src/test/java/org/elasticsearch/action/bulk/BulkWithUpdatesIT.java
+++ b/core/src/test/java/org/elasticsearch/action/bulk/BulkWithUpdatesIT.java
@@ -450,156 +450,7 @@ public class BulkWithUpdatesIT extends ESIntegTestCase {
assertHitCount(countResponse, numDocs);
}
- /*
- Test for https://github.com/elastic/elasticsearch/issues/3444
- */
- public void testBulkUpdateDocAsUpsertWithParent() throws Exception {
- client().admin().indices().prepareCreate("test")
- .setSettings("index.mapping.single_type", false)
- .addMapping("parent", "{\"parent\":{}}", XContentType.JSON)
- .addMapping("child", "{\"child\": {\"_parent\": {\"type\": \"parent\"}}}", XContentType.JSON)
- .execute().actionGet();
- ensureGreen();
- BulkRequestBuilder builder = client().prepareBulk();
-
- // It's important to use JSON parsing here and request objects: issue 3444 is related to incomplete option parsing
- byte[] addParent = new BytesArray(
- "{" +
- " \"index\" : {" +
- " \"_index\" : \"test\"," +
- " \"_type\" : \"parent\"," +
- " \"_id\" : \"parent1\"" +
- " }" +
- "}" +
- "\n" +
- "{" +
- " \"field1\" : \"value1\"" +
- "}" +
- "\n").array();
-
- byte[] addChild = new BytesArray(
- "{" +
- " \"update\" : {" +
- " \"_index\" : \"test\"," +
- " \"_type\" : \"child\"," +
- " \"_id\" : \"child1\"," +
- " \"parent\" : \"parent1\"" +
- " }" +
- "}" +
- "\n" +
- "{" +
- " \"doc\" : {" +
- " \"field1\" : \"value1\"" +
- " }," +
- " \"doc_as_upsert\" : \"true\"" +
- "}" +
- "\n").array();
-
- builder.add(addParent, 0, addParent.length, XContentType.JSON);
- builder.add(addChild, 0, addChild.length, XContentType.JSON);
-
- BulkResponse bulkResponse = builder.get();
- assertThat(bulkResponse.getItems().length, equalTo(2));
- assertThat(bulkResponse.getItems()[0].isFailed(), equalTo(false));
- assertThat(bulkResponse.getItems()[1].isFailed(), equalTo(false));
-
- client().admin().indices().prepareRefresh("test").get();
-
- //we check that the _parent field was set on the child document by using the has parent query
- SearchResponse searchResponse = client().prepareSearch("test")
- .setQuery(QueryBuilders.hasParentQuery("parent", QueryBuilders.matchAllQuery(), false))
- .get();
-
- assertNoFailures(searchResponse);
- assertSearchHits(searchResponse, "child1");
- }
-
- /*
- Test for https://github.com/elastic/elasticsearch/issues/3444
- */
- public void testBulkUpdateUpsertWithParent() throws Exception {
- assertAcked(prepareCreate("test")
- .setSettings("index.mapping.single_type", false)
- .addMapping("parent", "{\"parent\":{}}", XContentType.JSON)
- .addMapping("child", "{\"child\": {\"_parent\": {\"type\": \"parent\"}}}", XContentType.JSON));
- ensureGreen();
-
- BulkRequestBuilder builder = client().prepareBulk();
-
- byte[] addParent = new BytesArray(
- "{" +
- " \"index\" : {" +
- " \"_index\" : \"test\"," +
- " \"_type\" : \"parent\"," +
- " \"_id\" : \"parent1\"" +
- " }" +
- "}" +
- "\n" +
- "{" +
- " \"field1\" : \"value1\"" +
- "}" +
- "\n").array();
-
- byte[] addChild1 = new BytesArray(
- "{" +
- " \"update\" : {" +
- " \"_index\" : \"test\"," +
- " \"_type\" : \"child\"," +
- " \"_id\" : \"child1\"," +
- " \"parent\" : \"parent1\"" +
- " }" +
- "}" +
- "\n" +
- "{" +
- " \"script\" : {" +
- " \"inline\" : \"ctx._source.field2 = 'value2'\"" +
- " }," +
- " \"lang\" : \"" + CustomScriptPlugin.NAME + "\"," +
- " \"upsert\" : {" +
- " \"field1\" : \"value1'\"" +
- " }" +
- "}" +
- "\n").array();
-
- byte[] addChild2 = new BytesArray(
- "{" +
- " \"update\" : {" +
- " \"_index\" : \"test\"," +
- " \"_type\" : \"child\"," +
- " \"_id\" : \"child1\"," +
- " \"parent\" : \"parent1\"" +
- " }" +
- "}" +
- "\n" +
- "{" +
- " \"script\" : \"ctx._source.field2 = 'value2'\"," +
- " \"upsert\" : {" +
- " \"field1\" : \"value1'\"" +
- " }" +
- "}" +
- "\n").array();
-
- builder.add(addParent, 0, addParent.length, XContentType.JSON);
- builder.add(addChild1, 0, addChild1.length, XContentType.JSON);
- builder.add(addChild2, 0, addChild2.length, XContentType.JSON);
-
- BulkResponse bulkResponse = builder.get();
- assertThat(bulkResponse.getItems().length, equalTo(3));
- assertThat(bulkResponse.getItems()[0].isFailed(), equalTo(false));
- assertThat(bulkResponse.getItems()[1].isFailed(), equalTo(false));
- assertThat(bulkResponse.getItems()[2].isFailed(), equalTo(true));
- assertThat(bulkResponse.getItems()[2].getFailure().getCause().getCause().getMessage(),
- equalTo("script_lang not supported [painless]"));
-
- client().admin().indices().prepareRefresh("test").get();
-
- SearchResponse searchResponse = client().prepareSearch("test")
- .setQuery(QueryBuilders.hasParentQuery("parent", QueryBuilders.matchAllQuery(), false))
- .get();
-
- assertSearchHits(searchResponse, "child1");
- }
/*
* Test for https://github.com/elastic/elasticsearch/issues/8365
diff --git a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java
index 711804153cf..e711117fb6e 100644
--- a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java
+++ b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java
@@ -63,8 +63,6 @@ import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_BLOCKS_ME
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_BLOCKS_READ;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_BLOCKS_WRITE;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_READ_ONLY;
-import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
@@ -824,27 +822,6 @@ public class IndexAliasesIT extends ESIntegTestCase {
}
}
- public void testAliasesFilterWithHasChildQuery() throws Exception {
- assertAcked(prepareCreate("my-index")
- .setSettings("index.mapping.single_type", false)
- .addMapping("parent")
- .addMapping("child", "_parent", "type=parent")
- );
- client().prepareIndex("my-index", "parent", "1").setSource("{}", XContentType.JSON).get();
- client().prepareIndex("my-index", "child", "2").setSource("{}", XContentType.JSON).setParent("1").get();
- refresh();
-
- assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter1", hasChildQuery("child", matchAllQuery(), ScoreMode.None)));
- assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter2", hasParentQuery("parent", matchAllQuery(), false)));
-
- SearchResponse response = client().prepareSearch("filter1").get();
- assertHitCount(response, 1);
- assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
- response = client().prepareSearch("filter2").get();
- assertHitCount(response, 1);
- assertThat(response.getHits().getAt(0).getId(), equalTo("2"));
- }
-
public void testAliasesWithBlocks() {
createIndex("test");
ensureGreen();
diff --git a/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java
index cd6622368c9..9e199f71cea 100644
--- a/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java
@@ -153,24 +153,6 @@ public class InnerHitBuilderTests extends ESTestCase {
assertThat(innerHitBuilders.get(leafInnerHits.getName()), notNullValue());
}
- public void testInlineLeafInnerHitsHasChildQuery() throws Exception {
- InnerHitBuilder leafInnerHits = randomInnerHits();
- HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder("type", new MatchAllQueryBuilder(), ScoreMode.None)
- .innerHit(leafInnerHits, false);
- Map innerHitBuilders = new HashMap<>();
- hasChildQueryBuilder.extractInnerHitBuilders(innerHitBuilders);
- assertThat(innerHitBuilders.get(leafInnerHits.getName()), notNullValue());
- }
-
- public void testInlineLeafInnerHitsHasParentQuery() throws Exception {
- InnerHitBuilder leafInnerHits = randomInnerHits();
- HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder("type", new MatchAllQueryBuilder(), false)
- .innerHit(leafInnerHits, false);
- Map innerHitBuilders = new HashMap<>();
- hasParentQueryBuilder.extractInnerHitBuilders(innerHitBuilders);
- assertThat(innerHitBuilders.get(leafInnerHits.getName()), notNullValue());
- }
-
public void testInlineLeafInnerHitsNestedQueryViaBoolQuery() {
InnerHitBuilder leafInnerHits = randomInnerHits();
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("path", new MatchAllQueryBuilder(), ScoreMode.None)
@@ -181,25 +163,6 @@ public class InnerHitBuilderTests extends ESTestCase {
assertThat(innerHitBuilders.get(leafInnerHits.getName()), notNullValue());
}
- public void testInlineLeafInnerHitsNestedQueryViaDisMaxQuery() {
- InnerHitBuilder leafInnerHits1 = randomInnerHits();
- NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("path", new MatchAllQueryBuilder(), ScoreMode.None)
- .innerHit(leafInnerHits1, false);
-
- InnerHitBuilder leafInnerHits2 = randomInnerHits();
- HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder("type", new MatchAllQueryBuilder(), ScoreMode.None)
- .innerHit(leafInnerHits2, false);
-
- DisMaxQueryBuilder disMaxQueryBuilder = new DisMaxQueryBuilder();
- disMaxQueryBuilder.add(nestedQueryBuilder);
- disMaxQueryBuilder.add(hasChildQueryBuilder);
- Map innerHitBuilders = new HashMap<>();
- disMaxQueryBuilder.extractInnerHitBuilders(innerHitBuilders);
- assertThat(innerHitBuilders.size(), equalTo(2));
- assertThat(innerHitBuilders.get(leafInnerHits1.getName()), notNullValue());
- assertThat(innerHitBuilders.get(leafInnerHits2.getName()), notNullValue());
- }
-
public void testInlineLeafInnerHitsNestedQueryViaConstantScoreQuery() {
InnerHitBuilder leafInnerHits = randomInnerHits();
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("path", new MatchAllQueryBuilder(), ScoreMode.None)
@@ -252,43 +215,6 @@ public class InnerHitBuilderTests extends ESTestCase {
assertThat(innerHitsContext.getInnerHits().size(), equalTo(0));
}
- public void testBuild_ignoreUnmappedHasChildQuery() throws Exception {
- QueryShardContext queryShardContext = mock(QueryShardContext.class);
- when(queryShardContext.documentMapper("type")).thenReturn(null);
- SearchContext searchContext = mock(SearchContext.class);
- when(searchContext.getQueryShardContext()).thenReturn(queryShardContext);
-
- InnerHitBuilder leafInnerHits = randomInnerHits();
- HasChildQueryBuilder query1 = new HasChildQueryBuilder("type", new MatchAllQueryBuilder(), ScoreMode.None)
- .innerHit(leafInnerHits, false);
- expectThrows(IllegalStateException.class, () -> query1.innerHit().build(searchContext, new InnerHitsContext()));
-
- HasChildQueryBuilder query2 = new HasChildQueryBuilder("type", new MatchAllQueryBuilder(), ScoreMode.None)
- .innerHit(leafInnerHits, true);
- InnerHitsContext innerHitsContext = new InnerHitsContext();
- query2.innerHit().build(searchContext, innerHitsContext);
- assertThat(innerHitsContext.getInnerHits().size(), equalTo(0));
- }
-
- public void testBuild_ingoreUnmappedHasParentQuery() throws Exception {
- QueryShardContext queryShardContext = mock(QueryShardContext.class);
- when(queryShardContext.documentMapper("type")).thenReturn(null);
- SearchContext searchContext = mock(SearchContext.class);
- when(searchContext.getQueryShardContext()).thenReturn(queryShardContext);
-
- InnerHitBuilder leafInnerHits = randomInnerHits();
- HasParentQueryBuilder query1 = new HasParentQueryBuilder("type", new MatchAllQueryBuilder(), false)
- .innerHit(leafInnerHits, false);
- expectThrows(IllegalStateException.class, () -> query1.innerHit().build(searchContext, new InnerHitsContext()));
-
- HasParentQueryBuilder query2 = new HasParentQueryBuilder("type", new MatchAllQueryBuilder(), false)
- .innerHit(leafInnerHits, true);
- InnerHitsContext innerHitsContext = new InnerHitsContext();
- query2.innerHit().build(searchContext, innerHitsContext);
- assertThat(innerHitsContext.getInnerHits().size(), equalTo(0));
- }
-
-
public static InnerHitBuilder randomInnerHits() {
return randomInnerHits(true, true);
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
index 267963878ea..ed4fbcd53cd 100644
--- a/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java
@@ -61,7 +61,7 @@ public class NestedQueryBuilderTests extends AbstractQueryTestCase NestedQueryBuilder.parseScoreMode(null));
+ assertEquals("No score mode for child query [null] found", e.getMessage());
+ }
+
+ /**
+ * Failure should not change (and the value should never match anything...).
+ */
+ public void testThatUnrecognizedFromStringThrowsException() {
+ IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
+ () -> NestedQueryBuilder.parseScoreMode("unrecognized value"));
+ assertEquals("No score mode for child query [unrecognized value] found", e.getMessage());
+ }
}
diff --git a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java
index 8514096b837..96767c99b9d 100644
--- a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java
+++ b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java
@@ -270,8 +270,6 @@ public class SearchModuleTests extends ModuleTestCase {
"geo_distance",
"geo_polygon",
"geo_shape",
- "has_child",
- "has_parent",
"ids",
"match",
"match_all",
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java
index 3e74b9c2187..464f081f6c9 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java
@@ -21,7 +21,7 @@ package org.elasticsearch.search.aggregations.bucket.filter;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java
index 9092c3e0280..2a284746bf6 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java
@@ -21,7 +21,7 @@ package org.elasticsearch.search.aggregations.bucket.global;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java
index f3e151721bf..1a702e94024 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java
@@ -21,7 +21,7 @@ package org.elasticsearch.search.aggregations.bucket.missing;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java
index 7b410723666..a330c8a146e 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java
@@ -21,7 +21,7 @@ package org.elasticsearch.search.aggregations.bucket.nested;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java
index f918024733e..069ac038295 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java
@@ -21,7 +21,7 @@ package org.elasticsearch.search.aggregations.bucket.nested;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java
index 1c4fb6d2a65..23facaf8fd2 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java
@@ -20,7 +20,7 @@ package org.elasticsearch.search.aggregations.bucket.sampler;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
@@ -42,4 +42,4 @@ public class InternalSamplerTests extends InternalSingleBucketAggregationTestCas
protected Writeable.Reader instanceReader() {
return InternalSampler::new;
}
-}
\ No newline at end of file
+}
diff --git a/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java b/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java
index 6fbda92ba26..8eca5055646 100644
--- a/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java
+++ b/core/src/test/java/org/elasticsearch/search/fetch/subphase/InnerHitsIT.java
@@ -55,8 +55,6 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
@@ -246,268 +244,6 @@ public class InnerHitsIT extends ESIntegTestCase {
}
}
- public void testSimpleParentChild() throws Exception {
- assertAcked(prepareCreate("articles")
- .setSettings("index.mapping.single_type", false)
- .addMapping("article", "title", "type=text")
- .addMapping("comment", "_parent", "type=article", "message", "type=text,fielddata=true")
- );
-
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("articles", "article", "1").setSource("title", "quick brown fox"));
- requests.add(client().prepareIndex("articles", "comment", "1").setParent("1").setSource("message", "fox eat quick"));
- requests.add(client().prepareIndex("articles", "comment", "2").setParent("1").setSource("message", "fox ate rabbit x y z"));
- requests.add(client().prepareIndex("articles", "comment", "3").setParent("1").setSource("message", "rabbit got away"));
- requests.add(client().prepareIndex("articles", "article", "2").setSource("title", "big gray elephant"));
- requests.add(client().prepareIndex("articles", "comment", "4").setParent("2").setSource("message", "elephant captured"));
- requests.add(client().prepareIndex("articles", "comment", "5").setParent("2").setSource("message", "mice squashed by elephant x"));
- requests.add(client().prepareIndex("articles", "comment", "6").setParent("2").setSource("message", "elephant scared by mice x y"));
- indexRandom(true, requests);
-
- SearchResponse response = client().prepareSearch("articles")
- .setQuery(hasChildQuery("comment", matchQuery("message", "fox"), ScoreMode.None)
- .innerHit(new InnerHitBuilder(), false))
- .get();
- assertNoFailures(response);
- assertHitCount(response, 1);
- assertSearchHit(response, 1, hasId("1"));
- assertThat(response.getHits().getAt(0).getShard(), notNullValue());
-
- assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
- SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
- assertThat(innerHits.getTotalHits(), equalTo(2L));
-
- assertThat(innerHits.getAt(0).getId(), equalTo("1"));
- assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
- assertThat(innerHits.getAt(1).getId(), equalTo("2"));
- assertThat(innerHits.getAt(1).getType(), equalTo("comment"));
-
- response = client().prepareSearch("articles")
- .setQuery(hasChildQuery("comment", matchQuery("message", "elephant"), ScoreMode.None)
- .innerHit(new InnerHitBuilder(), false))
- .get();
- assertNoFailures(response);
- assertHitCount(response, 1);
- assertSearchHit(response, 1, hasId("2"));
-
- assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
- innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
- assertThat(innerHits.getTotalHits(), equalTo(3L));
-
- assertThat(innerHits.getAt(0).getId(), equalTo("4"));
- assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
- assertThat(innerHits.getAt(1).getId(), equalTo("5"));
- assertThat(innerHits.getAt(1).getType(), equalTo("comment"));
- assertThat(innerHits.getAt(2).getId(), equalTo("6"));
- assertThat(innerHits.getAt(2).getType(), equalTo("comment"));
-
- response = client().prepareSearch("articles")
- .setQuery(
- hasChildQuery("comment", matchQuery("message", "fox"), ScoreMode.None).innerHit(
- new InnerHitBuilder()
- .addDocValueField("message")
- .setHighlightBuilder(new HighlightBuilder().field("message"))
- .setExplain(true).setSize(1)
- .addScriptField("script", new Script(ScriptType.INLINE, MockScriptEngine.NAME, "5",
- Collections.emptyMap())),
- false)
- ).get();
- assertNoFailures(response);
- innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
- assertThat(innerHits.getHits().length, equalTo(1));
- assertThat(innerHits.getAt(0).getHighlightFields().get("message").getFragments()[0].string(), equalTo("fox eat quick"));
- assertThat(innerHits.getAt(0).getExplanation().toString(), containsString("weight(message:fox"));
- assertThat(innerHits.getAt(0).getFields().get("message").getValue().toString(), equalTo("eat"));
- assertThat(innerHits.getAt(0).getFields().get("script").getValue().toString(), equalTo("5"));
- }
-
- public void testRandomParentChild() throws Exception {
- assertAcked(prepareCreate("idx")
- .setSettings("index.mapping.single_type", false)
- .addMapping("parent")
- .addMapping("child1", "_parent", "type=parent")
- .addMapping("child2", "_parent", "type=parent")
- );
- int numDocs = scaledRandomIntBetween(5, 50);
- List requestBuilders = new ArrayList<>();
-
- int child1 = 0;
- int child2 = 0;
- int[] child1InnerObjects = new int[numDocs];
- int[] child2InnerObjects = new int[numDocs];
- for (int parent = 0; parent < numDocs; parent++) {
- String parentId = String.format(Locale.ENGLISH, "%03d", parent);
- requestBuilders.add(client().prepareIndex("idx", "parent", parentId).setSource("{}", XContentType.JSON));
-
- int numChildDocs = child1InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
- int limit = child1 + numChildDocs;
- for (; child1 < limit; child1++) {
- requestBuilders.add(client().prepareIndex("idx", "child1",
- String.format(Locale.ENGLISH, "%04d", child1)).setParent(parentId).setSource("{}", XContentType.JSON));
- }
- numChildDocs = child2InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
- limit = child2 + numChildDocs;
- for (; child2 < limit; child2++) {
- requestBuilders.add(client().prepareIndex("idx", "child2",
- String.format(Locale.ENGLISH, "%04d", child2)).setParent(parentId).setSource("{}", XContentType.JSON));
- }
- }
- indexRandom(true, requestBuilders);
-
- int size = randomIntBetween(0, numDocs);
- BoolQueryBuilder boolQuery = new BoolQueryBuilder();
- boolQuery.should(constantScoreQuery(hasChildQuery("child1", matchAllQuery(), ScoreMode.None)
- .innerHit(new InnerHitBuilder().setName("a")
- .addSort(new FieldSortBuilder("_uid").order(SortOrder.ASC)).setSize(size), false)));
- boolQuery.should(constantScoreQuery(hasChildQuery("child2", matchAllQuery(), ScoreMode.None)
- .innerHit(new InnerHitBuilder().setName("b")
- .addSort(new FieldSortBuilder("_uid").order(SortOrder.ASC)).setSize(size), false)));
- SearchResponse searchResponse = client().prepareSearch("idx")
- .setSize(numDocs)
- .setTypes("parent")
- .addSort("_uid", SortOrder.ASC)
- .setQuery(boolQuery)
- .get();
-
- assertNoFailures(searchResponse);
- assertHitCount(searchResponse, numDocs);
- assertThat(searchResponse.getHits().getHits().length, equalTo(numDocs));
-
- int offset1 = 0;
- int offset2 = 0;
- for (int parent = 0; parent < numDocs; parent++) {
- SearchHit searchHit = searchResponse.getHits().getAt(parent);
- assertThat(searchHit.getType(), equalTo("parent"));
- assertThat(searchHit.getId(), equalTo(String.format(Locale.ENGLISH, "%03d", parent)));
- assertThat(searchHit.getShard(), notNullValue());
-
- SearchHits inner = searchHit.getInnerHits().get("a");
- assertThat(inner.getTotalHits(), equalTo((long) child1InnerObjects[parent]));
- for (int child = 0; child < child1InnerObjects[parent] && child < size; child++) {
- SearchHit innerHit = inner.getAt(child);
- assertThat(innerHit.getType(), equalTo("child1"));
- String childId = String.format(Locale.ENGLISH, "%04d", offset1 + child);
- assertThat(innerHit.getId(), equalTo(childId));
- assertThat(innerHit.getNestedIdentity(), nullValue());
- }
- offset1 += child1InnerObjects[parent];
-
- inner = searchHit.getInnerHits().get("b");
- assertThat(inner.getTotalHits(), equalTo((long) child2InnerObjects[parent]));
- for (int child = 0; child < child2InnerObjects[parent] && child < size; child++) {
- SearchHit innerHit = inner.getAt(child);
- assertThat(innerHit.getType(), equalTo("child2"));
- String childId = String.format(Locale.ENGLISH, "%04d", offset2 + child);
- assertThat(innerHit.getId(), equalTo(childId));
- assertThat(innerHit.getNestedIdentity(), nullValue());
- }
- offset2 += child2InnerObjects[parent];
- }
- }
-
- public void testInnerHitsOnHasParent() throws Exception {
- assertAcked(prepareCreate("stack")
- .setSettings("index.mapping.single_type", false)
- .addMapping("question", "body", "type=text")
- .addMapping("answer", "_parent", "type=question", "body", "type=text")
- );
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("stack", "question", "1").setSource("body", "I'm using HTTPS + Basic authentication "
- + "to protect a resource. How can I throttle authentication attempts to protect against brute force attacks?"));
- requests.add(client().prepareIndex("stack", "answer", "1").setParent("1").setSource("body",
- "install fail2ban and enable rules for apache"));
- requests.add(client().prepareIndex("stack", "question", "2").setSource("body",
- "I have firewall rules set up and also denyhosts installed.\\ndo I also need to install fail2ban?"));
- requests.add(client().prepareIndex("stack", "answer", "2").setParent("2").setSource("body",
- "Denyhosts protects only ssh; Fail2Ban protects all daemons."));
- indexRandom(true, requests);
-
- SearchResponse response = client().prepareSearch("stack")
- .setTypes("answer")
- .addSort("_uid", SortOrder.ASC)
- .setQuery(
- boolQuery()
- .must(matchQuery("body", "fail2ban"))
- .must(hasParentQuery("question", matchAllQuery(), false).innerHit(new InnerHitBuilder(), false))
- ).get();
- assertNoFailures(response);
- assertHitCount(response, 2);
-
- SearchHit searchHit = response.getHits().getAt(0);
- assertThat(searchHit.getId(), equalTo("1"));
- assertThat(searchHit.getType(), equalTo("answer"));
- assertThat(searchHit.getInnerHits().get("question").getTotalHits(), equalTo(1L));
- assertThat(searchHit.getInnerHits().get("question").getAt(0).getType(), equalTo("question"));
- assertThat(searchHit.getInnerHits().get("question").getAt(0).getId(), equalTo("1"));
-
- searchHit = response.getHits().getAt(1);
- assertThat(searchHit.getId(), equalTo("2"));
- assertThat(searchHit.getType(), equalTo("answer"));
- assertThat(searchHit.getInnerHits().get("question").getTotalHits(), equalTo(1L));
- assertThat(searchHit.getInnerHits().get("question").getAt(0).getType(), equalTo("question"));
- assertThat(searchHit.getInnerHits().get("question").getAt(0).getId(), equalTo("2"));
- }
-
- public void testParentChildMultipleLayers() throws Exception {
- assertAcked(prepareCreate("articles")
- .setSettings("index.mapping.single_type", false)
- .addMapping("article", "title", "type=text")
- .addMapping("comment", "_parent", "type=article", "message", "type=text")
- .addMapping("remark", "_parent", "type=comment", "message", "type=text")
- );
-
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("articles", "article", "1").setSource("title", "quick brown fox"));
- requests.add(client().prepareIndex("articles", "comment", "1").setParent("1").setSource("message", "fox eat quick"));
- requests.add(client().prepareIndex("articles", "remark", "1").setParent("1").setRouting("1").setSource("message", "good"));
- requests.add(client().prepareIndex("articles", "article", "2").setSource("title", "big gray elephant"));
- requests.add(client().prepareIndex("articles", "comment", "2").setParent("2").setSource("message", "elephant captured"));
- requests.add(client().prepareIndex("articles", "remark", "2").setParent("2").setRouting("2").setSource("message", "bad"));
- indexRandom(true, requests);
-
- SearchResponse response = client().prepareSearch("articles")
- .setQuery(hasChildQuery("comment",
- hasChildQuery("remark", matchQuery("message", "good"), ScoreMode.None).innerHit(new InnerHitBuilder(), false),
- ScoreMode.None).innerHit(new InnerHitBuilder(), false))
- .get();
-
- assertNoFailures(response);
- assertHitCount(response, 1);
- assertSearchHit(response, 1, hasId("1"));
-
- assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
- SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
- assertThat(innerHits.getTotalHits(), equalTo(1L));
- assertThat(innerHits.getAt(0).getId(), equalTo("1"));
- assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
-
- innerHits = innerHits.getAt(0).getInnerHits().get("remark");
- assertThat(innerHits.getTotalHits(), equalTo(1L));
- assertThat(innerHits.getAt(0).getId(), equalTo("1"));
- assertThat(innerHits.getAt(0).getType(), equalTo("remark"));
-
- response = client().prepareSearch("articles")
- .setQuery(hasChildQuery("comment",
- hasChildQuery("remark", matchQuery("message", "bad"), ScoreMode.None).innerHit(new InnerHitBuilder(), false),
- ScoreMode.None).innerHit(new InnerHitBuilder(), false))
- .get();
-
- assertNoFailures(response);
- assertHitCount(response, 1);
- assertSearchHit(response, 1, hasId("2"));
-
- assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
- innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
- assertThat(innerHits.getTotalHits(), equalTo(1L));
- assertThat(innerHits.getAt(0).getId(), equalTo("2"));
- assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
-
- innerHits = innerHits.getAt(0).getInnerHits().get("remark");
- assertThat(innerHits.getTotalHits(), equalTo(1L));
- assertThat(innerHits.getAt(0).getId(), equalTo("2"));
- assertThat(innerHits.getAt(0).getType(), equalTo("remark"));
- }
-
public void testNestedMultipleLayers() throws Exception {
assertAcked(prepareCreate("articles").addMapping("article", jsonBuilder().startObject()
.startObject("article").startObject("properties")
@@ -724,92 +460,6 @@ public class InnerHitsIT extends ESIntegTestCase {
assertThat(messages.getAt(0).getNestedIdentity().getChild(), nullValue());
}
- public void testRoyals() throws Exception {
- assertAcked(
- prepareCreate("royals")
- .setSettings("index.mapping.single_type", false)
- .addMapping("king")
- .addMapping("prince", "_parent", "type=king")
- .addMapping("duke", "_parent", "type=prince")
- .addMapping("earl", "_parent", "type=duke")
- .addMapping("baron", "_parent", "type=earl")
- );
-
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("royals", "king", "king").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "prince", "prince").setParent("king").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "duke", "duke").setParent("prince").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "earl", "earl1").setParent("duke").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "earl", "earl2").setParent("duke").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "earl", "earl3").setParent("duke").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "earl", "earl4").setParent("duke").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "baron", "baron1").setParent("earl1").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "baron", "baron2").setParent("earl2").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "baron", "baron3").setParent("earl3").setRouting("king")
- .setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("royals", "baron", "baron4").setParent("earl4").setRouting("king")
- .setSource("{}", XContentType.JSON));
- indexRandom(true, requests);
-
- SearchResponse response = client().prepareSearch("royals")
- .setTypes("duke")
- .setQuery(boolQuery()
- .filter(hasParentQuery("prince",
- hasParentQuery("king", matchAllQuery(), false).innerHit(new InnerHitBuilder().setName("kings"), false),
- false).innerHit(new InnerHitBuilder().setName("princes"), false)
- )
- .filter(hasChildQuery("earl",
- hasChildQuery("baron", matchAllQuery(), ScoreMode.None)
- .innerHit(new InnerHitBuilder().setName("barons"), false),
- ScoreMode.None).innerHit(new InnerHitBuilder()
- .addSort(SortBuilders.fieldSort("_uid").order(SortOrder.ASC))
- .setName("earls")
- .setSize(4), false)
- )
- )
- .get();
- assertHitCount(response, 1);
- assertThat(response.getHits().getAt(0).getId(), equalTo("duke"));
-
- SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("earls");
- assertThat(innerHits.getTotalHits(), equalTo(4L));
- assertThat(innerHits.getAt(0).getId(), equalTo("earl1"));
- assertThat(innerHits.getAt(1).getId(), equalTo("earl2"));
- assertThat(innerHits.getAt(2).getId(), equalTo("earl3"));
- assertThat(innerHits.getAt(3).getId(), equalTo("earl4"));
-
- SearchHits innerInnerHits = innerHits.getAt(0).getInnerHits().get("barons");
- assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
- assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron1"));
-
- innerInnerHits = innerHits.getAt(1).getInnerHits().get("barons");
- assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
- assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron2"));
-
- innerInnerHits = innerHits.getAt(2).getInnerHits().get("barons");
- assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
- assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron3"));
-
- innerInnerHits = innerHits.getAt(3).getInnerHits().get("barons");
- assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
- assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron4"));
-
- innerHits = response.getHits().getAt(0).getInnerHits().get("princes");
- assertThat(innerHits.getTotalHits(), equalTo(1L));
- assertThat(innerHits.getAt(0).getId(), equalTo("prince"));
-
- innerInnerHits = innerHits.getAt(0).getInnerHits().get("kings");
- assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
- assertThat(innerInnerHits.getAt(0).getId(), equalTo("king"));
- }
-
public void testMatchesQueriesNestedInnerHits() throws Exception {
XContentBuilder builder = jsonBuilder().startObject()
.startObject("type1")
@@ -914,84 +564,6 @@ public class InnerHitsIT extends ESIntegTestCase {
}
}
- public void testMatchesQueriesParentChildInnerHits() throws Exception {
- assertAcked(prepareCreate("index")
- .setSettings("index.mapping.single_type", false)
- .addMapping("child", "_parent", "type=parent"));
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("index", "parent", "1").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("index", "child", "1").setParent("1").setSource("field", "value1"));
- requests.add(client().prepareIndex("index", "child", "2").setParent("1").setSource("field", "value2"));
- requests.add(client().prepareIndex("index", "parent", "2").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("index", "child", "3").setParent("2").setSource("field", "value1"));
- indexRandom(true, requests);
-
- SearchResponse response = client().prepareSearch("index")
- .setQuery(hasChildQuery("child", matchQuery("field", "value1").queryName("_name1"), ScoreMode.None)
- .innerHit(new InnerHitBuilder(), false))
- .addSort("_uid", SortOrder.ASC)
- .get();
- assertHitCount(response, 2);
- assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getTotalHits(), equalTo(1L));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name1"));
-
- assertThat(response.getHits().getAt(1).getId(), equalTo("2"));
- assertThat(response.getHits().getAt(1).getInnerHits().get("child").getTotalHits(), equalTo(1L));
- assertThat(response.getHits().getAt(1).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
- assertThat(response.getHits().getAt(1).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name1"));
-
- QueryBuilder query = hasChildQuery("child", matchQuery("field", "value2").queryName("_name2"), ScoreMode.None)
- .innerHit(new InnerHitBuilder(), false);
- response = client().prepareSearch("index")
- .setQuery(query)
- .addSort("_uid", SortOrder.ASC)
- .get();
- assertHitCount(response, 1);
- assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getTotalHits(), equalTo(1L));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
- assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name2"));
- }
-
- public void testDontExplode() throws Exception {
- assertAcked(prepareCreate("index1")
- .setSettings("index.mapping.single_type", false)
- .addMapping("child", "_parent", "type=parent"));
- List requests = new ArrayList<>();
- requests.add(client().prepareIndex("index1", "parent", "1").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("index1", "child", "1").setParent("1").setSource("field", "value1"));
- indexRandom(true, requests);
-
- QueryBuilder query = hasChildQuery("child", matchQuery("field", "value1"), ScoreMode.None)
- .innerHit(new InnerHitBuilder().setSize(ArrayUtil.MAX_ARRAY_LENGTH - 1), false);
- SearchResponse response = client().prepareSearch("index1")
- .setQuery(query)
- .get();
- assertNoFailures(response);
- assertHitCount(response, 1);
-
- assertAcked(prepareCreate("index2").addMapping("type", "nested", "type=nested"));
- client().prepareIndex("index2", "type", "1").setSource(jsonBuilder().startObject()
- .startArray("nested")
- .startObject()
- .field("field", "value1")
- .endObject()
- .endArray()
- .endObject())
- .setRefreshPolicy(IMMEDIATE)
- .get();
-
- query = nestedQuery("nested", matchQuery("nested.field", "value1"), ScoreMode.Avg)
- .innerHit(new InnerHitBuilder().setSize(ArrayUtil.MAX_ARRAY_LENGTH - 1), false);
- response = client().prepareSearch("index2")
- .setQuery(query)
- .get();
- assertNoFailures(response);
- assertHitCount(response, 1);
- }
-
public void testNestedSourceFiltering() throws Exception {
assertAcked(prepareCreate("index1").addMapping("message", "comments", "type=nested"));
client().prepareIndex("index1", "message", "1").setSource(jsonBuilder().startObject()
@@ -1021,25 +593,6 @@ public class InnerHitsIT extends ESIntegTestCase {
equalTo("fox ate rabbit x y z"));
}
- public void testNestedInnerHitWrappedInParentChildInnerhit() throws Exception {
- assertAcked(prepareCreate("test")
- .setSettings("index.mapping.single_type", false)
- .addMapping("child_type", "_parent", "type=parent_type", "nested_type", "type=nested"));
- client().prepareIndex("test", "parent_type", "1").setSource("key", "value").get();
- client().prepareIndex("test", "child_type", "2").setParent("1").setSource("nested_type", Collections.singletonMap("key", "value"))
- .get();
- refresh();
- SearchResponse response = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchQuery("key", "value"))
- .should(hasChildQuery("child_type", nestedQuery("nested_type", matchAllQuery(), ScoreMode.None)
- .innerHit(new InnerHitBuilder(), false), ScoreMode.None).innerHit(new InnerHitBuilder(), false)))
- .get();
- assertHitCount(response, 1);
- SearchHit hit = response.getHits().getAt(0);
- assertThat(hit.getInnerHits().get("child_type").getAt(0).field("_parent").getValue(), equalTo("1"));
- assertThat(hit.getInnerHits().get("child_type").getAt(0).getInnerHits().get("nested_type").getAt(0).field("_parent"), nullValue());
- }
-
public void testInnerHitsWithIgnoreUnmapped() throws Exception {
assertAcked(prepareCreate("index1")
.setSettings("index.mapping.single_type", false)
@@ -1062,17 +615,6 @@ public class InnerHitsIT extends ESIntegTestCase {
assertNoFailures(response);
assertHitCount(response, 2);
assertSearchHits(response, "1", "3");
-
- response = client().prepareSearch("index1", "index2")
- .setQuery(boolQuery()
- .should(hasChildQuery("child_type", matchAllQuery(), ScoreMode.None).ignoreUnmapped(true)
- .innerHit(new InnerHitBuilder(), true))
- .should(termQuery("key", "value"))
- )
- .get();
- assertNoFailures(response);
- assertHitCount(response, 2);
- assertSearchHits(response, "1", "3");
}
}
diff --git a/docs/java-api/aggregations/bucket/children-aggregation.asciidoc b/docs/java-api/aggregations/bucket/children-aggregation.asciidoc
index 1bf8a5b26e6..f6a23fdafe9 100644
--- a/docs/java-api/aggregations/bucket/children-aggregation.asciidoc
+++ b/docs/java-api/aggregations/bucket/children-aggregation.asciidoc
@@ -24,7 +24,7 @@ Import Aggregation definition classes:
[source,java]
--------------------------------------------------
-import org.elasticsearch.search.aggregations.bucket.children.Children;
+import org.elasticsearch.join.aggregations.Children;
--------------------------------------------------
[source,java]
diff --git a/modules/parent-join/build.gradle b/modules/parent-join/build.gradle
new file mode 100644
index 00000000000..67bcc9d54e8
--- /dev/null
+++ b/modules/parent-join/build.gradle
@@ -0,0 +1,24 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+esplugin {
+ description 'This module adds the support parent-child queries and aggregations'
+ classname 'org.elasticsearch.join.ParentJoinPlugin'
+ hasClientJar = true
+}
diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/ParentJoinPlugin.java b/modules/parent-join/src/main/java/org/elasticsearch/join/ParentJoinPlugin.java
new file mode 100644
index 00000000000..dec3950836a
--- /dev/null
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/ParentJoinPlugin.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.join;
+
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.join.aggregations.ChildrenAggregationBuilder;
+import org.elasticsearch.join.aggregations.InternalChildren;
+import org.elasticsearch.join.query.HasChildQueryBuilder;
+import org.elasticsearch.join.query.HasParentQueryBuilder;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.plugins.SearchPlugin;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class ParentJoinPlugin extends Plugin implements SearchPlugin {
+ public ParentJoinPlugin(Settings settings) {}
+
+ @Override
+ public List> getQueries() {
+ return Arrays.asList(
+ new QuerySpec<>(HasChildQueryBuilder.NAME, HasChildQueryBuilder::new, HasChildQueryBuilder::fromXContent),
+ new QuerySpec<>(HasParentQueryBuilder.NAME, HasParentQueryBuilder::new, HasParentQueryBuilder::fromXContent)
+ );
+ }
+
+ @Override
+ public List getAggregations() {
+ return Collections.singletonList(
+ new AggregationSpec(ChildrenAggregationBuilder.NAME, ChildrenAggregationBuilder::new, ChildrenAggregationBuilder::parse)
+ .addResultReader(InternalChildren::new)
+ );
+ }
+
+
+}
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/Children.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/Children.java
similarity index 94%
rename from core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/Children.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/Children.java
index b1e4b2877a3..394c690709d 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/Children.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/Children.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregation;
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregationBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java
similarity index 99%
rename from core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregationBuilder.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java
index 3a0d2fff982..d04b1f0a660 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregationBuilder.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParsingException;
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregatorFactory.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregatorFactory.java
similarity index 98%
rename from core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregatorFactory.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregatorFactory.java
index b0a4c64305a..800be74ba6f 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ChildrenAggregatorFactory.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregatorFactory.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.apache.lucene.search.Query;
import org.elasticsearch.search.aggregations.Aggregator;
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildren.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/InternalChildren.java
similarity index 97%
rename from core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildren.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/InternalChildren.java
index 05a38c8cd59..05cd40e3d33 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildren.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/InternalChildren.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.search.aggregations.InternalAggregations;
diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/JoinAggregationBuilders.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/JoinAggregationBuilders.java
new file mode 100644
index 00000000000..73522a68b45
--- /dev/null
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/JoinAggregationBuilders.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.join.aggregations;
+
+public abstract class JoinAggregationBuilders {
+ /**
+ * Create a new {@link Children} aggregation with the given name.
+ */
+ public static ChildrenAggregationBuilder children(String name, String childType) {
+ return new ChildrenAggregationBuilder(name, childType);
+ }
+}
diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregator.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregator.java
similarity index 99%
rename from core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregator.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregator.java
index 37a443e9bab..c1ffb097abc 100644
--- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregator.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregator.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
diff --git a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java
similarity index 94%
rename from core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
rename to modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java
index 18ad7f9f310..494c5e498e1 100644
--- a/core/src/main/java/org/elasticsearch/index/query/HasChildQueryBuilder.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.elasticsearch.index.query;
+package org.elasticsearch.join.query;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
@@ -38,6 +38,14 @@ import org.elasticsearch.index.fielddata.IndexParentChildFieldData;
import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.ParentFieldMapper;
+import org.elasticsearch.index.query.AbstractQueryBuilder;
+import org.elasticsearch.index.query.InnerHitBuilder;
+import org.elasticsearch.index.query.NestedQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.index.query.QueryRewriteContext;
+import org.elasticsearch.index.query.QueryShardContext;
+import org.elasticsearch.index.query.QueryShardException;
import java.io.IOException;
import java.util.Locale;
@@ -210,7 +218,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder parameters() throws Exception {
+ return createParameters();
+ }
+}
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenIT.java
similarity index 92%
rename from core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenIT.java
index bfe483ca890..8da6dbcdf6c 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenIT.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket;
+package org.elasticsearch.join.aggregations;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.index.IndexRequestBuilder;
@@ -26,27 +26,33 @@ import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.InternalAggregation;
-import org.elasticsearch.search.aggregations.bucket.children.Children;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ESIntegTestCase;
+import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
+import org.elasticsearch.test.ESIntegTestCase.Scope;
+import org.junit.Before;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import static org.elasticsearch.search.aggregations.AggregationBuilders.children;
+import static org.elasticsearch.join.aggregations.JoinAggregationBuilders.children;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
@@ -59,13 +65,28 @@ import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
-@ESIntegTestCase.SuiteScopeTestCase
+@ClusterScope(scope = Scope.SUITE)
public class ChildrenIT extends ESIntegTestCase {
-
private static final Map categoryToControl = new HashMap<>();
@Override
- public void setupSuiteScopeCluster() throws Exception {
+ protected boolean ignoreExternalCluster() {
+ return true;
+ }
+
+ @Override
+ protected Collection> nodePlugins() {
+ return Collections.singleton(ParentJoinPlugin.class);
+ }
+
+ @Override
+ protected Collection> transportClientPlugins() {
+ return nodePlugins();
+ }
+
+ @Before
+ public void setupCluster() throws Exception {
+ categoryToControl.clear();
assertAcked(
prepareCreate("test")
.setSettings("index.mapping.single_type", false)
@@ -95,7 +116,8 @@ public class ChildrenIT extends ESIntegTestCase {
control.articleIds.add(id);
}
- requests.add(client().prepareIndex("test", "article", id).setCreate(true).setSource("category", categories, "randomized", true));
+ requests.add(client()
+ .prepareIndex("test", "article", id).setCreate(true).setSource("category", categories, "randomized", true));
}
String[] commenters = new String[randomIntBetween(5, 50)];
@@ -116,17 +138,24 @@ public class ChildrenIT extends ESIntegTestCase {
control.commenterToCommentId.put(commenter, ids = new HashSet<>());
}
ids.add(idValue);
- requests.add(client().prepareIndex("test", "comment", idValue).setCreate(true).setParent(articleId).setSource("commenter", commenter));
+ requests.add(client().prepareIndex("test", "comment", idValue)
+ .setCreate(true).setParent(articleId).setSource("commenter", commenter));
}
}
}
- requests.add(client().prepareIndex("test", "article", "a").setSource("category", new String[]{"a"}, "randomized", false));
- requests.add(client().prepareIndex("test", "article", "b").setSource("category", new String[]{"a", "b"}, "randomized", false));
- requests.add(client().prepareIndex("test", "article", "c").setSource("category", new String[]{"a", "b", "c"}, "randomized", false));
- requests.add(client().prepareIndex("test", "article", "d").setSource("category", new String[]{"c"}, "randomized", false));
- requests.add(client().prepareIndex("test", "comment", "a").setParent("a").setSource("{}", XContentType.JSON));
- requests.add(client().prepareIndex("test", "comment", "c").setParent("c").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("test", "article", "a")
+ .setSource("category", new String[]{"a"}, "randomized", false));
+ requests.add(client().prepareIndex("test", "article", "b")
+ .setSource("category", new String[]{"a", "b"}, "randomized", false));
+ requests.add(client().prepareIndex("test", "article", "c")
+ .setSource("category", new String[]{"a", "b", "c"}, "randomized", false));
+ requests.add(client().prepareIndex("test", "article", "d")
+ .setSource("category", new String[]{"c"}, "randomized", false));
+ requests.add(client().prepareIndex("test", "comment", "a")
+ .setParent("a").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("test", "comment", "c")
+ .setParent("c").setSource("{}", XContentType.JSON));
indexRandom(true, requests);
ensureSearchable("test");
@@ -155,7 +184,8 @@ public class ChildrenIT extends ESIntegTestCase {
Children childrenBucket = categoryBucket.getAggregations().get("to_comment");
assertThat(childrenBucket.getName(), equalTo("to_comment"));
assertThat(childrenBucket.getDocCount(), equalTo((long) entry1.getValue().commentIds.size()));
- assertThat((long) ((InternalAggregation)childrenBucket).getProperty("_count"), equalTo((long) entry1.getValue().commentIds.size()));
+ assertThat((long) ((InternalAggregation)childrenBucket).getProperty("_count"),
+ equalTo((long) entry1.getValue().commentIds.size()));
Terms commentersTerms = childrenBucket.getAggregations().get("commenters");
assertThat((Terms) ((InternalAggregation)childrenBucket).getProperty("commenters"), sameInstance(commentersTerms));
@@ -283,7 +313,7 @@ public class ChildrenIT extends ESIntegTestCase {
public void testNonExistingChildType() throws Exception {
SearchResponse searchResponse = client().prepareSearch("test")
.addAggregation(
-children("non-existing", "xyz")
+ children("non-existing", "xyz")
).get();
assertSearchResponse(searchResponse);
@@ -304,7 +334,8 @@ children("non-existing", "xyz")
);
List requests = new ArrayList<>();
- requests.add(client().prepareIndex(indexName, masterType, "1").setSource("brand", "Levis", "name", "Style 501", "material", "Denim"));
+ requests.add(client().prepareIndex(indexName, masterType, "1")
+ .setSource("brand", "Levis", "name", "Style 501", "material", "Denim"));
requests.add(client().prepareIndex(indexName, childType, "0").setParent("1").setSource("color", "blue", "size", "32"));
requests.add(client().prepareIndex(indexName, childType, "1").setParent("1").setSource("color", "blue", "size", "34"));
requests.add(client().prepareIndex(indexName, childType, "2").setParent("1").setSource("color", "blue", "size", "36"));
@@ -312,7 +343,8 @@ children("non-existing", "xyz")
requests.add(client().prepareIndex(indexName, childType, "4").setParent("1").setSource("color", "black", "size", "40"));
requests.add(client().prepareIndex(indexName, childType, "5").setParent("1").setSource("color", "gray", "size", "36"));
- requests.add(client().prepareIndex(indexName, masterType, "2").setSource("brand", "Wrangler", "name", "Regular Cut", "material", "Leather"));
+ requests.add(client().prepareIndex(indexName, masterType, "2")
+ .setSource("brand", "Wrangler", "name", "Regular Cut", "material", "Leather"));
requests.add(client().prepareIndex(indexName, childType, "6").setParent("2").setSource("color", "blue", "size", "32"));
requests.add(client().prepareIndex(indexName, childType, "7").setParent("2").setSource("color", "blue", "size", "34"));
requests.add(client().prepareIndex(indexName, childType, "8").setParent("2").setSource("color", "black", "size", "36"));
@@ -425,7 +457,7 @@ children("non-existing", "xyz")
.setSize(0)
.addAggregation(AggregationBuilders.terms("towns").field("town")
.subAggregation(AggregationBuilders.terms("parent_names").field("name")
-.subAggregation(AggregationBuilders.children("child_docs", "childType"))
+.subAggregation(children("child_docs", "childType"))
)
)
.get();
@@ -468,5 +500,4 @@ children("non-existing", "xyz")
this.category = category;
}
}
-
}
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenTests.java b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenTests.java
similarity index 78%
rename from core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenTests.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenTests.java
index 4098e85c62e..85a97c4b9b4 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenTests.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ChildrenTests.java
@@ -17,13 +17,22 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket;
+package org.elasticsearch.join.aggregations;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.search.aggregations.BaseAggregationTestCase;
-import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
+
+import java.util.Collection;
+import java.util.Collections;
public class ChildrenTests extends BaseAggregationTestCase {
+ @Override
+ protected Collection> getPlugins() {
+ return Collections.singleton(ParentJoinPlugin.class);
+ }
+
@Override
protected ChildrenAggregationBuilder createTestAggregatorBuilder() {
String name = randomAlphaOfLengthBetween(3, 20);
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/InternalChildrenTests.java
similarity index 91%
rename from core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/InternalChildrenTests.java
index b248d5ed981..afcbc953ebb 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/InternalChildrenTests.java
@@ -17,11 +17,11 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.search.aggregations.InternalAggregations;
-import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase;
+import org.elasticsearch.search.aggregations.InternalSingleBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregatorTests.java b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregatorTests.java
similarity index 99%
rename from core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregatorTests.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregatorTests.java
index 17152bc450a..0a00b2d1c26 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/ParentToChildrenAggregatorTests.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/aggregations/ParentToChildrenAggregatorTests.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.search.aggregations.bucket.children;
+package org.elasticsearch.join.aggregations;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.SortedDocValuesField;
diff --git a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java b/modules/parent-join/src/test/java/org/elasticsearch/join/query/ChildQuerySearchIT.java
similarity index 87%
rename from core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/query/ChildQuerySearchIT.java
index 697352c5edc..ed910ac89e6 100644
--- a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/query/ChildQuerySearchIT.java
@@ -16,17 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.elasticsearch.search.child;
+package org.elasticsearch.join.query;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
+import org.elasticsearch.action.bulk.BulkRequestBuilder;
+import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.explain.ExplainResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
+import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
import org.elasticsearch.common.settings.Settings;
@@ -34,8 +37,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.HasChildQueryBuilder;
-import org.elasticsearch.index.query.HasParentQueryBuilder;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.InnerHitBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
@@ -43,6 +44,8 @@ import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
@@ -62,6 +65,8 @@ import org.hamcrest.Matchers;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -72,8 +77,6 @@ import java.util.Set;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
-import static org.elasticsearch.index.query.QueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.QueryBuilders.idsQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
@@ -83,6 +86,8 @@ import static org.elasticsearch.index.query.QueryBuilders.prefixQuery;
import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.fieldValueFactorFunction;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.weightFactorFunction;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@@ -100,6 +105,21 @@ import static org.hamcrest.Matchers.notNullValue;
@ClusterScope(scope = Scope.SUITE)
public class ChildQuerySearchIT extends ESIntegTestCase {
+
+ @Override
+ protected boolean ignoreExternalCluster() {
+ return true;
+ }
+
+ @Override
+ protected Collection> nodePlugins() {
+ return Collections.singleton(ParentJoinPlugin.class);
+ }
+
+ @Override
+ protected Collection> transportClientPlugins() {
+ return nodePlugins();
+ }
@Override
public Settings indexSettings() {
@@ -145,26 +165,30 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1"));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchAllQuery()).filter(hasParentQuery("parent", termQuery("p_field", "p_value1"), false))).execute()
+ .setQuery(boolQuery().must(matchAllQuery())
+ .filter(hasParentQuery("parent", termQuery("p_field", "p_value1"), false))).execute()
.actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1"));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchAllQuery()).filter(hasParentQuery("child", termQuery("c_field", "c_value1"), false))).execute()
+ .setQuery(boolQuery().must(matchAllQuery())
+ .filter(hasParentQuery("child", termQuery("c_field", "c_value1"), false))).execute()
.actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("gc1"));
- searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("parent", termQuery("p_field", "p_value1"), false)).execute()
+ searchResponse = client().prepareSearch("test")
+ .setQuery(hasParentQuery("parent", termQuery("p_field", "p_value1"), false)).execute()
.actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1"));
- searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("child", termQuery("c_field", "c_value1"), false)).execute()
+ searchResponse = client().prepareSearch("test")
+ .setQuery(hasParentQuery("child", termQuery("c_field", "c_value1"), false)).execute()
.actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
@@ -209,7 +233,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
refresh();
// TEST FETCHING _parent from child
- SearchResponse searchResponse = client().prepareSearch("test").setQuery(idsQuery("child").addIds("c1")).storedFields("_parent").execute()
+ SearchResponse searchResponse = client().prepareSearch("test")
+ .setQuery(idsQuery("child").addIds("c1")).storedFields("_parent").execute()
.actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
@@ -284,7 +309,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
builders.add(client().prepareIndex("test", "child", Integer.toString(i)).setSource("c_field", i).setParent("" + 0));
}
for (int i = 0; i < 10; i++) {
- builders.add(client().prepareIndex("test", "child", Integer.toString(i + 10)).setSource("c_field", i + 10).setParent(Integer.toString(i)));
+ builders.add(client().prepareIndex("test", "child", Integer.toString(i + 10))
+ .setSource("c_field", i + 10).setParent(Integer.toString(i)));
}
if (randomBoolean()) {
@@ -445,9 +471,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse searchResponse = client()
.prepareSearch("test")
- .setQuery(hasChildQuery("child", boolQuery().should(termQuery("c_field", "red")).should(termQuery("c_field", "yellow")), ScoreMode.None))
+ .setQuery(hasChildQuery("child",
+ boolQuery().should(termQuery("c_field", "red")).should(termQuery("c_field", "yellow")), ScoreMode.None))
.addAggregation(AggregationBuilders.global("global").subAggregation(
- AggregationBuilders.filter("filter", boolQuery().should(termQuery("c_field", "red")).should(termQuery("c_field", "yellow"))).subAggregation(
+ AggregationBuilders.filter("filter",
+ boolQuery().should(termQuery("c_field", "red")).should(termQuery("c_field", "yellow"))).subAggregation(
AggregationBuilders.terms("facet1").field("c_field")))).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
@@ -523,7 +551,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertNoFailures(searchResponse);
searchResponse = client().prepareSearch("test").setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
- .setQuery(boolQuery().mustNot(hasParentQuery("parent", boolQuery().should(queryStringQuery("p_field:*")), false))).execute()
+ .setQuery(boolQuery().mustNot(hasParentQuery("parent",
+ boolQuery().should(queryStringQuery("p_field:*")), false))).execute()
.actionGet();
assertNoFailures(searchResponse);
}
@@ -570,7 +599,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.get();
assertHitCount(countResponse, 1L);
- countResponse = client().prepareSearch("test").setSize(0).setQuery(hasParentQuery("parent", termQuery("p_field", "1"), true))
+ countResponse = client().prepareSearch("test").setSize(0)
+ .setQuery(hasParentQuery("parent", termQuery("p_field", "1"), true))
.get();
assertHitCount(countResponse, 1L);
@@ -579,7 +609,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.get();
assertHitCount(countResponse, 1L);
- countResponse = client().prepareSearch("test").setSize(0).setQuery(constantScoreQuery(hasParentQuery("parent", termQuery("p_field", "1"), false)))
+ countResponse = client().prepareSearch("test").setSize(0)
+ .setQuery(constantScoreQuery(hasParentQuery("parent", termQuery("p_field", "1"), false)))
.get();
assertHitCount(countResponse, 1L);
}
@@ -685,11 +716,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse response = client()
.prepareSearch("test")
.setQuery(
- QueryBuilders.hasChildQuery(
- "child",
- QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
- fieldValueFactorFunction("c_field1"))
- .boostMode(CombineFunction.REPLACE), ScoreMode.Total)).get();
+ hasChildQuery(
+ "child",
+ QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
+ fieldValueFactorFunction("c_field1"))
+ .boostMode(CombineFunction.REPLACE), ScoreMode.Total)).get();
assertThat(response.getHits().getTotalHits(), equalTo(3L));
assertThat(response.getHits().getHits()[0].getId(), equalTo("1"));
@@ -702,11 +733,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
response = client()
.prepareSearch("test")
.setQuery(
- QueryBuilders.hasChildQuery(
- "child",
- QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
- fieldValueFactorFunction("c_field1"))
- .boostMode(CombineFunction.REPLACE), ScoreMode.Max)).get();
+ hasChildQuery(
+ "child",
+ QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
+ fieldValueFactorFunction("c_field1"))
+ .boostMode(CombineFunction.REPLACE), ScoreMode.Max)).get();
assertThat(response.getHits().getTotalHits(), equalTo(3L));
assertThat(response.getHits().getHits()[0].getId(), equalTo("3"));
@@ -719,11 +750,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
response = client()
.prepareSearch("test")
.setQuery(
- QueryBuilders.hasChildQuery(
- "child",
- QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
- fieldValueFactorFunction("c_field1"))
- .boostMode(CombineFunction.REPLACE), ScoreMode.Avg)).get();
+ hasChildQuery(
+ "child",
+ QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
+ fieldValueFactorFunction("c_field1"))
+ .boostMode(CombineFunction.REPLACE), ScoreMode.Avg)).get();
assertThat(response.getHits().getTotalHits(), equalTo(3L));
assertThat(response.getHits().getHits()[0].getId(), equalTo("3"));
@@ -736,11 +767,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
response = client()
.prepareSearch("test")
.setQuery(
- QueryBuilders.hasParentQuery(
- "parent",
- QueryBuilders.functionScoreQuery(matchQuery("p_field1", "p_value3"),
- fieldValueFactorFunction("p_field2"))
- .boostMode(CombineFunction.REPLACE), true))
+ hasParentQuery(
+ "parent",
+ QueryBuilders.functionScoreQuery(matchQuery("p_field1", "p_value3"),
+ fieldValueFactorFunction("p_field2"))
+ .boostMode(CombineFunction.REPLACE), true))
.addSort(SortBuilders.fieldSort("c_field3")).addSort(SortBuilders.scoreSort()).get();
assertThat(response.getHits().getTotalHits(), equalTo(7L));
@@ -769,7 +800,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
ensureGreen();
SearchResponse response = client().prepareSearch("test")
- .setQuery(QueryBuilders.hasChildQuery("child", matchQuery("text", "value"), ScoreMode.None)).get();
+ .setQuery(hasChildQuery("child", matchQuery("text", "value"), ScoreMode.None)).get();
assertNoFailures(response);
assertThat(response.getHits().getTotalHits(), equalTo(0L));
@@ -777,20 +808,21 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.setRefreshPolicy(RefreshPolicy.IMMEDIATE).get();
response = client().prepareSearch("test")
- .setQuery(QueryBuilders.hasChildQuery("child", matchQuery("text", "value"), ScoreMode.None)).get();
+ .setQuery(hasChildQuery("child", matchQuery("text", "value"), ScoreMode.None)).get();
assertNoFailures(response);
assertThat(response.getHits().getTotalHits(), equalTo(0L));
- response = client().prepareSearch("test").setQuery(QueryBuilders.hasChildQuery("child", matchQuery("text", "value"), ScoreMode.Max))
+ response = client().prepareSearch("test").setQuery(hasChildQuery("child", matchQuery("text", "value"), ScoreMode.Max))
.get();
assertNoFailures(response);
assertThat(response.getHits().getTotalHits(), equalTo(0L));
- response = client().prepareSearch("test").setQuery(QueryBuilders.hasParentQuery("parent", matchQuery("text", "value"), false)).get();
+ response = client().prepareSearch("test")
+ .setQuery(hasParentQuery("parent", matchQuery("text", "value"), false)).get();
assertNoFailures(response);
assertThat(response.getHits().getTotalHits(), equalTo(0L));
- response = client().prepareSearch("test").setQuery(QueryBuilders.hasParentQuery("parent", matchQuery("text", "value"), true))
+ response = client().prepareSearch("test").setQuery(hasParentQuery("parent", matchQuery("text", "value"), true))
.get();
assertNoFailures(response);
assertThat(response.getHits().getTotalHits(), equalTo(0L));
@@ -818,7 +850,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchAllQuery()).filter(hasParentQuery("parent", termQuery("p_field", 1), false))).get();
+ .setQuery(boolQuery().must(matchAllQuery())
+ .filter(hasParentQuery("parent", termQuery("p_field", 1), false))).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("2"));
@@ -873,12 +906,14 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertSearchHit(searchResponse, 1, hasId("2"));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchAllQuery()).filter(boolQuery().must(hasChildQuery("child", matchQuery("c_field", 1), ScoreMode.None))))
+ .setQuery(boolQuery().must(matchAllQuery())
+ .filter(boolQuery().must(hasChildQuery("child", matchQuery("c_field", 1), ScoreMode.None))))
.get();
assertSearchHit(searchResponse, 1, hasId("1"));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(matchAllQuery()).filter(boolQuery().must(hasParentQuery("parent", matchQuery("p_field", 1), false)))).get();
+ .setQuery(boolQuery().must(matchAllQuery())
+ .filter(boolQuery().must(hasParentQuery("parent", matchQuery("p_field", 1), false)))).get();
assertSearchHit(searchResponse, 1, hasId("2"));
}
@@ -974,7 +1009,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().admin().indices().prepareRefresh("test").get();
}
- searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow"), ScoreMode.Total))
+ searchResponse = client().prepareSearch("test")
+ .setQuery(hasChildQuery("child", termQuery("c_field", "yellow"), ScoreMode.Total))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
@@ -1009,7 +1045,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().prepareIndex("test", "child", "c5").setSource("c_field", "x").setParent("p2").get();
refresh();
- SearchResponse searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.Total))
+ SearchResponse searchResponse = client()
+ .prepareSearch("test").setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.Total))
.setMinScore(3) // Score needs to be 3 or above!
.get();
assertNoFailures(searchResponse);
@@ -1219,7 +1256,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
createIndex("test");
ensureGreen();
- PutMappingResponse putMappingResponse = client().admin().indices().preparePutMapping("test").setType("child").setSource("number", "type=integer")
+ PutMappingResponse putMappingResponse = client().admin().indices()
+ .preparePutMapping("test").setType("child").setSource("number", "type=integer")
.get();
assertThat(putMappingResponse.isAcknowledged(), equalTo(true));
@@ -1269,13 +1307,15 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
ScoreMode scoreMode = randomFrom(ScoreMode.values());
SearchResponse searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "blue"), scoreMode)).filter(boolQuery().mustNot(termQuery("p_field", "3"))))
+ .setQuery(boolQuery().must(hasChildQuery("child", termQuery("c_field", "blue"), scoreMode))
+ .filter(boolQuery().mustNot(termQuery("p_field", "3"))))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
searchResponse = client().prepareSearch("test")
- .setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "red"), scoreMode)).filter(boolQuery().mustNot(termQuery("p_field", "3"))))
+ .setQuery(boolQuery().must(hasChildQuery("child", termQuery("c_field", "red"), scoreMode))
+ .filter(boolQuery().mustNot(termQuery("p_field", "3"))))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
@@ -1293,25 +1333,29 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().prepareIndex("test", "child", "c1").setSource("c_field", "1").setParent(parentId).get();
refresh();
- SearchResponse searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "1"), ScoreMode.Max).queryName("test"))
+ SearchResponse searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child",
+ termQuery("c_field", "1"), ScoreMode.Max).queryName("test"))
.get();
assertHitCount(searchResponse, 1L);
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
- searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("parent", termQuery("p_field", "1"), true).queryName("test"))
+ searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("parent",
+ termQuery("p_field", "1"), true).queryName("test"))
.get();
assertHitCount(searchResponse, 1L);
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
- searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasChildQuery("child", termQuery("c_field", "1"), ScoreMode.None).queryName("test")))
+ searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasChildQuery("child",
+ termQuery("c_field", "1"), ScoreMode.None).queryName("test")))
.get();
assertHitCount(searchResponse, 1L);
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("test"));
- searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasParentQuery("parent", termQuery("p_field", "1"), false).queryName("test")))
+ searchResponse = client().prepareSearch("test").setQuery(constantScoreQuery(hasParentQuery("parent",
+ termQuery("p_field", "1"), false).queryName("test")))
.get();
assertHitCount(searchResponse, 1L);
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
@@ -1400,7 +1444,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
for (int i = 0; i < 2; i++) {
SearchResponse searchResponse = client().prepareSearch()
.setQuery(boolQuery().must(matchAllQuery()).filter(boolQuery()
- .must(QueryBuilders.hasChildQuery("child", matchQuery("c_field", "red"), ScoreMode.None))
+ .must(hasChildQuery("child", matchQuery("c_field", "red"), ScoreMode.None))
.must(matchAllQuery())))
.get();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
@@ -1412,7 +1456,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse searchResponse = client().prepareSearch()
.setQuery(boolQuery().must(matchAllQuery()).filter(boolQuery()
- .must(QueryBuilders.hasChildQuery("child", matchQuery("c_field", "red"), ScoreMode.None))
+ .must(hasChildQuery("child", matchQuery("c_field", "red"), ScoreMode.None))
.must(matchAllQuery())))
.get();
@@ -1478,7 +1522,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse resp;
resp = client().prepareSearch("test")
- .setSource(new SearchSourceBuilder().query(QueryBuilders.hasChildQuery("posts", QueryBuilders.matchQuery("field", "bar"), ScoreMode.None)))
+ .setSource(new SearchSourceBuilder().query(hasChildQuery("posts",
+ QueryBuilders.matchQuery("field", "bar"), ScoreMode.None)))
.get();
assertHitCount(resp, 1L);
}
@@ -1580,8 +1625,10 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
QueryBuilders.functionScoreQuery(constantScoreQuery(QueryBuilders.termQuery("foo", "two")),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(weightFactorFunction(1)),
- new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("foo", "three"), weightFactorFunction(1)),
- new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("foo", "four"), weightFactorFunction(1))
+ new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("foo", "three"),
+ weightFactorFunction(1)),
+ new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("foo", "four"),
+ weightFactorFunction(1))
}).boostMode(CombineFunction.REPLACE).scoreMode(FiltersFunctionScoreQuery.ScoreMode.SUM), scoreMode)
.minMaxChildren(minChildren, maxChildren != null ? maxChildren : HasChildQueryBuilder.DEFAULT_MAX_CHILDREN);
@@ -1916,7 +1963,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
try {
client().prepareSearch("test")
- .setQuery(QueryBuilders.hasChildQuery("child", matchAllQuery(), ScoreMode.None))
+ .setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.None))
.get();
fail();
} catch (SearchPhaseExecutionException e) {
@@ -1932,7 +1979,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
refresh();
//make sure that when we explicitly set a type, the inner query is executed in the context of the parent type instead
SearchResponse searchResponse = client().prepareSearch("test").setTypes("child-type").setQuery(
- QueryBuilders.hasParentQuery("parent-type", new IdsQueryBuilder().addIds("parent-id"), false)).get();
+ hasParentQuery("parent-type", new IdsQueryBuilder().addIds("parent-id"), false)).get();
assertSearchHits(searchResponse, "child-id");
}
@@ -1945,7 +1992,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
refresh();
//make sure that when we explicitly set a type, the inner query is executed in the context of the child type instead
SearchResponse searchResponse = client().prepareSearch("test").setTypes("parent-type").setQuery(
- QueryBuilders.hasChildQuery("child-type", new IdsQueryBuilder().addIds("child-id"), ScoreMode.None)).get();
+ hasChildQuery("child-type", new IdsQueryBuilder().addIds("child-id"), ScoreMode.None)).get();
assertSearchHits(searchResponse, "parent-id");
}
@@ -1955,8 +2002,10 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.addMapping("parent-type", "searchText", "type=text,term_vector=with_positions_offsets,index_options=offsets")
.addMapping("child-type", "_parent", "type=parent-type", "searchText",
"type=text,term_vector=with_positions_offsets,index_options=offsets"));
- client().prepareIndex("test", "parent-type", "parent-id").setSource("searchText", "quick brown fox").get();
- client().prepareIndex("test", "child-type", "child-id").setParent("parent-id").setSource("searchText", "quick brown fox").get();
+ client().prepareIndex("test", "parent-type", "parent-id")
+ .setSource("searchText", "quick brown fox").get();
+ client().prepareIndex("test", "child-type", "child-id")
+ .setParent("parent-id").setSource("searchText", "quick brown fox").get();
refresh();
String[] highlightTypes = new String[] {"plain", "fvh", "postings"};
@@ -1988,4 +2037,177 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
}
}
+ public void testAliasesFilterWithHasChildQuery() throws Exception {
+ assertAcked(prepareCreate("my-index")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("parent")
+ .addMapping("child", "_parent", "type=parent")
+ );
+ client().prepareIndex("my-index", "parent", "1").setSource("{}", XContentType.JSON).get();
+ client().prepareIndex("my-index", "child", "2").setSource("{}", XContentType.JSON).setParent("1").get();
+ refresh();
+
+ assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter1",
+ hasChildQuery("child", matchAllQuery(), ScoreMode.None)));
+ assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter2",
+ hasParentQuery("parent", matchAllQuery(), false)));
+
+ SearchResponse response = client().prepareSearch("filter1").get();
+ assertHitCount(response, 1);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
+ response = client().prepareSearch("filter2").get();
+ assertHitCount(response, 1);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("2"));
+ }
+
+ /*
+ Test for https://github.com/elastic/elasticsearch/issues/3444
+ */
+ public void testBulkUpdateDocAsUpsertWithParent() throws Exception {
+ client().admin().indices().prepareCreate("test")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("parent", "{\"parent\":{}}", XContentType.JSON)
+ .addMapping("child", "{\"child\": {\"_parent\": {\"type\": \"parent\"}}}", XContentType.JSON)
+ .execute().actionGet();
+ ensureGreen();
+
+ BulkRequestBuilder builder = client().prepareBulk();
+
+ // It's important to use JSON parsing here and request objects: issue 3444 is related to incomplete option parsing
+ byte[] addParent = new BytesArray(
+ "{" +
+ " \"index\" : {" +
+ " \"_index\" : \"test\"," +
+ " \"_type\" : \"parent\"," +
+ " \"_id\" : \"parent1\"" +
+ " }" +
+ "}" +
+ "\n" +
+ "{" +
+ " \"field1\" : \"value1\"" +
+ "}" +
+ "\n").array();
+
+ byte[] addChild = new BytesArray(
+ "{" +
+ " \"update\" : {" +
+ " \"_index\" : \"test\"," +
+ " \"_type\" : \"child\"," +
+ " \"_id\" : \"child1\"," +
+ " \"parent\" : \"parent1\"" +
+ " }" +
+ "}" +
+ "\n" +
+ "{" +
+ " \"doc\" : {" +
+ " \"field1\" : \"value1\"" +
+ " }," +
+ " \"doc_as_upsert\" : \"true\"" +
+ "}" +
+ "\n").array();
+
+ builder.add(addParent, 0, addParent.length, XContentType.JSON);
+ builder.add(addChild, 0, addChild.length, XContentType.JSON);
+
+ BulkResponse bulkResponse = builder.get();
+ assertThat(bulkResponse.getItems().length, equalTo(2));
+ assertThat(bulkResponse.getItems()[0].isFailed(), equalTo(false));
+ assertThat(bulkResponse.getItems()[1].isFailed(), equalTo(false));
+
+ client().admin().indices().prepareRefresh("test").get();
+
+ //we check that the _parent field was set on the child document by using the has parent query
+ SearchResponse searchResponse = client().prepareSearch("test")
+ .setQuery(hasParentQuery("parent", QueryBuilders.matchAllQuery(), false))
+ .get();
+
+ assertNoFailures(searchResponse);
+ assertSearchHits(searchResponse, "child1");
+ }
+
+ /*
+ Test for https://github.com/elastic/elasticsearch/issues/3444
+ */
+ public void testBulkUpdateUpsertWithParent() throws Exception {
+ assertAcked(prepareCreate("test")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("parent", "{\"parent\":{}}", XContentType.JSON)
+ .addMapping("child", "{\"child\": {\"_parent\": {\"type\": \"parent\"}}}", XContentType.JSON));
+ ensureGreen();
+
+ BulkRequestBuilder builder = client().prepareBulk();
+
+ byte[] addParent = new BytesArray(
+ "{" +
+ " \"index\" : {" +
+ " \"_index\" : \"test\"," +
+ " \"_type\" : \"parent\"," +
+ " \"_id\" : \"parent1\"" +
+ " }" +
+ "}" +
+ "\n" +
+ "{" +
+ " \"field1\" : \"value1\"" +
+ "}" +
+ "\n").array();
+
+ byte[] addChild1 = new BytesArray(
+ "{" +
+ " \"update\" : {" +
+ " \"_index\" : \"test\"," +
+ " \"_type\" : \"child\"," +
+ " \"_id\" : \"child1\"," +
+ " \"parent\" : \"parent1\"" +
+ " }" +
+ "}" +
+ "\n" +
+ "{" +
+ " \"script\" : {" +
+ " \"inline\" : \"ctx._source.field2 = 'value2'\"" +
+ " }," +
+ " \"lang\" : \"" + InnerHitsIT.CustomScriptPlugin.NAME + "\"," +
+ " \"upsert\" : {" +
+ " \"field1\" : \"value1'\"" +
+ " }" +
+ "}" +
+ "\n").array();
+
+ byte[] addChild2 = new BytesArray(
+ "{" +
+ " \"update\" : {" +
+ " \"_index\" : \"test\"," +
+ " \"_type\" : \"child\"," +
+ " \"_id\" : \"child1\"," +
+ " \"parent\" : \"parent1\"" +
+ " }" +
+ "}" +
+ "\n" +
+ "{" +
+ " \"script\" : \"ctx._source.field2 = 'value2'\"," +
+ " \"upsert\" : {" +
+ " \"field1\" : \"value1'\"" +
+ " }" +
+ "}" +
+ "\n").array();
+
+ builder.add(addParent, 0, addParent.length, XContentType.JSON);
+ builder.add(addChild1, 0, addChild1.length, XContentType.JSON);
+ builder.add(addChild2, 0, addChild2.length, XContentType.JSON);
+
+ BulkResponse bulkResponse = builder.get();
+ assertThat(bulkResponse.getItems().length, equalTo(3));
+ assertThat(bulkResponse.getItems()[0].isFailed(), equalTo(false));
+ assertThat(bulkResponse.getItems()[1].isFailed(), equalTo(false));
+ assertThat(bulkResponse.getItems()[2].isFailed(), equalTo(true));
+ assertThat(bulkResponse.getItems()[2].getFailure().getCause().getCause().getMessage(),
+ equalTo("script_lang not supported [painless]"));
+
+ client().admin().indices().prepareRefresh("test").get();
+
+ SearchResponse searchResponse = client().prepareSearch("test")
+ .setQuery(hasParentQuery("parent", QueryBuilders.matchAllQuery(), false))
+ .get();
+
+ assertSearchHits(searchResponse, "child1");
+ }
}
diff --git a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java b/modules/parent-join/src/test/java/org/elasticsearch/join/query/HasChildQueryBuilderTests.java
similarity index 83%
rename from core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/query/HasChildQueryBuilderTests.java
index 49523fe923d..8f4fc9d0c34 100644
--- a/core/src/test/java/org/elasticsearch/index/query/HasChildQueryBuilderTests.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/query/HasChildQueryBuilderTests.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.index.query;
+package org.elasticsearch.join.query;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.search.TermInSetQuery;
@@ -40,7 +40,17 @@ import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.TypeFieldMapper;
import org.elasticsearch.index.mapper.Uid;
import org.elasticsearch.index.mapper.UidFieldMapper;
+import org.elasticsearch.index.query.IdsQueryBuilder;
+import org.elasticsearch.index.query.InnerHitBuilder;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryShardContext;
+import org.elasticsearch.index.query.QueryShardException;
+import org.elasticsearch.index.query.TermQueryBuilder;
+import org.elasticsearch.index.query.WrapperQueryBuilder;
import org.elasticsearch.index.similarity.SimilarityService;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.search.fetch.subphase.InnerHitsContext;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.sort.FieldSortBuilder;
@@ -48,10 +58,12 @@ import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.AbstractQueryTestCase;
import java.io.IOException;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -65,6 +77,11 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase> getPlugins() {
+ return Collections.singletonList(ParentJoinPlugin.class);
+ }
+
@Override
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
similarity = randomFrom("classic", "BM25");
@@ -97,7 +114,7 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase QueryBuilders.hasChildQuery(null, query, ScoreMode.None));
+ () -> hasChildQuery(null, query, ScoreMode.None));
assertEquals("[has_child] requires 'type' field", e.getMessage());
- e = expectThrows(IllegalArgumentException.class, () -> QueryBuilders.hasChildQuery("foo", null, ScoreMode.None));
+ e = expectThrows(IllegalArgumentException.class, () -> hasChildQuery("foo", null, ScoreMode.None));
assertEquals("[has_child] requires 'query' field", e.getMessage());
- e = expectThrows(IllegalArgumentException.class, () -> QueryBuilders.hasChildQuery("foo", query, null));
+ e = expectThrows(IllegalArgumentException.class, () -> hasChildQuery("foo", query, null));
assertEquals("[has_child] requires 'score_mode' field", e.getMessage());
int positiveValue = randomIntBetween(0, Integer.MAX_VALUE);
- HasChildQueryBuilder foo = QueryBuilders.hasChildQuery("foo", query, ScoreMode.None); // all good
+ HasChildQueryBuilder foo = hasChildQuery("foo", query, ScoreMode.None); // all good
e = expectThrows(IllegalArgumentException.class, () -> foo.minMaxChildren(randomIntBetween(Integer.MIN_VALUE, -1), positiveValue));
assertEquals("[has_child] requires non-negative 'min_children' field", e.getMessage());
@@ -225,7 +242,7 @@ public class HasChildQueryBuilderTests extends AbstractQueryTestCase HasChildQueryBuilder.parseScoreMode(null));
- assertEquals("No score mode for child query [null] found", e.getMessage());
- }
-
- /**
- * Failure should not change (and the value should never match anything...).
- */
- public void testThatUnrecognizedFromStringThrowsException() {
- IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
- () -> HasChildQueryBuilder.parseScoreMode("unrecognized value"));
- assertEquals("No score mode for child query [unrecognized value] found", e.getMessage());
- }
-
public void testIgnoreUnmapped() throws IOException {
final HasChildQueryBuilder queryBuilder = new HasChildQueryBuilder("unmapped", new MatchAllQueryBuilder(), ScoreMode.None);
queryBuilder.ignoreUnmapped(true);
diff --git a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java b/modules/parent-join/src/test/java/org/elasticsearch/join/query/HasParentQueryBuilderTests.java
similarity index 90%
rename from core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java
rename to modules/parent-join/src/test/java/org/elasticsearch/join/query/HasParentQueryBuilderTests.java
index 22ea2cc9c44..825dfede61e 100644
--- a/core/src/test/java/org/elasticsearch/index/query/HasParentQueryBuilderTests.java
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/query/HasParentQueryBuilderTests.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.index.query;
+package org.elasticsearch.join.query;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
@@ -28,6 +28,16 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.mapper.MapperService;
+import org.elasticsearch.index.query.IdsQueryBuilder;
+import org.elasticsearch.index.query.InnerHitBuilder;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryShardContext;
+import org.elasticsearch.index.query.QueryShardException;
+import org.elasticsearch.index.query.TermQueryBuilder;
+import org.elasticsearch.index.query.WrapperQueryBuilder;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.search.fetch.subphase.InnerHitsContext;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.sort.FieldSortBuilder;
@@ -35,9 +45,12 @@ import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.AbstractQueryTestCase;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -49,6 +62,11 @@ public class HasParentQueryBuilderTests extends AbstractQueryTestCase> getPlugins() {
+ return Collections.singletonList(ParentJoinPlugin.class);
+ }
+
@Override
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
mapperService.merge(PARENT_TYPE, new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(PARENT_TYPE,
@@ -79,7 +97,7 @@ public class HasParentQueryBuilderTests extends AbstractQueryTestCase QueryBuilders.hasParentQuery(null, query, false));
+ () -> hasParentQuery(null, query, false));
assertThat(e.getMessage(), equalTo("[has_parent] requires 'type' field"));
e = expectThrows(IllegalArgumentException.class,
- () -> QueryBuilders.hasParentQuery("foo", null, false));
+ () -> hasParentQuery("foo", null, false));
assertThat(e.getMessage(), equalTo("[has_parent] requires 'query' field"));
QueryShardContext context = createShardContext();
- HasParentQueryBuilder qb = QueryBuilders.hasParentQuery("just_a_type", new MatchAllQueryBuilder(), false);
+ HasParentQueryBuilder qb = hasParentQuery("just_a_type", new MatchAllQueryBuilder(), false);
QueryShardException qse = expectThrows(QueryShardException.class, () -> qb.doToQuery(context));
assertThat(qse.getMessage(), equalTo("[has_parent] no child types found for type [just_a_type]"));
}
diff --git a/modules/parent-join/src/test/java/org/elasticsearch/join/query/InnerHitsIT.java b/modules/parent-join/src/test/java/org/elasticsearch/join/query/InnerHitsIT.java
new file mode 100644
index 00000000000..ad8e49e9f5d
--- /dev/null
+++ b/modules/parent-join/src/test/java/org/elasticsearch/join/query/InnerHitsIT.java
@@ -0,0 +1,568 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.join.query;
+
+import org.apache.lucene.search.join.ScoreMode;
+import org.apache.lucene.util.ArrayUtil;
+import org.elasticsearch.action.index.IndexRequestBuilder;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.InnerHitBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.script.MockScriptEngine;
+import org.elasticsearch.script.MockScriptPlugin;
+import org.elasticsearch.script.Script;
+import org.elasticsearch.script.ScriptType;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.SearchHits;
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
+import org.elasticsearch.search.sort.FieldSortBuilder;
+import org.elasticsearch.search.sort.SortBuilders;
+import org.elasticsearch.search.sort.SortOrder;
+import org.elasticsearch.test.ESIntegTestCase;
+import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
+import org.elasticsearch.test.ESIntegTestCase.Scope;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.function.Function;
+
+import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHit;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+@ClusterScope(scope = Scope.SUITE)
+public class InnerHitsIT extends ESIntegTestCase {
+ @Override
+ protected boolean ignoreExternalCluster() {
+ return true;
+ }
+
+ @Override
+ protected Collection> nodePlugins() {
+ return Arrays.asList(ParentJoinPlugin.class, CustomScriptPlugin.class);
+ }
+
+ @Override
+ protected Collection> transportClientPlugins() {
+ return nodePlugins();
+ }
+
+ public static class CustomScriptPlugin extends MockScriptPlugin {
+ @Override
+ protected Map, Object>> pluginScripts() {
+ return Collections.singletonMap("5", script -> "5");
+ }
+ }
+
+ public void testSimpleParentChild() throws Exception {
+ assertAcked(prepareCreate("articles")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("article", "title", "type=text")
+ .addMapping("comment", "_parent", "type=article", "message", "type=text,fielddata=true")
+ );
+
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("articles", "article", "1").setSource("title", "quick brown fox"));
+ requests.add(client().prepareIndex("articles", "comment", "1").setParent("1").setSource("message", "fox eat quick"));
+ requests.add(client().prepareIndex("articles", "comment", "2").setParent("1").setSource("message", "fox ate rabbit x y z"));
+ requests.add(client().prepareIndex("articles", "comment", "3").setParent("1").setSource("message", "rabbit got away"));
+ requests.add(client().prepareIndex("articles", "article", "2").setSource("title", "big gray elephant"));
+ requests.add(client().prepareIndex("articles", "comment", "4").setParent("2").setSource("message", "elephant captured"));
+ requests.add(client().prepareIndex("articles", "comment", "5").setParent("2").setSource("message", "mice squashed by elephant x"));
+ requests.add(client().prepareIndex("articles", "comment", "6").setParent("2").setSource("message", "elephant scared by mice x y"));
+ indexRandom(true, requests);
+
+ SearchResponse response = client().prepareSearch("articles")
+ .setQuery(hasChildQuery("comment", matchQuery("message", "fox"), ScoreMode.None)
+ .innerHit(new InnerHitBuilder(), false))
+ .get();
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+ assertSearchHit(response, 1, hasId("1"));
+ assertThat(response.getHits().getAt(0).getShard(), notNullValue());
+
+ assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
+ SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
+ assertThat(innerHits.getTotalHits(), equalTo(2L));
+
+ assertThat(innerHits.getAt(0).getId(), equalTo("1"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
+ assertThat(innerHits.getAt(1).getId(), equalTo("2"));
+ assertThat(innerHits.getAt(1).getType(), equalTo("comment"));
+
+ response = client().prepareSearch("articles")
+ .setQuery(hasChildQuery("comment", matchQuery("message", "elephant"), ScoreMode.None)
+ .innerHit(new InnerHitBuilder(), false))
+ .get();
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+ assertSearchHit(response, 1, hasId("2"));
+
+ assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
+ innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
+ assertThat(innerHits.getTotalHits(), equalTo(3L));
+
+ assertThat(innerHits.getAt(0).getId(), equalTo("4"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
+ assertThat(innerHits.getAt(1).getId(), equalTo("5"));
+ assertThat(innerHits.getAt(1).getType(), equalTo("comment"));
+ assertThat(innerHits.getAt(2).getId(), equalTo("6"));
+ assertThat(innerHits.getAt(2).getType(), equalTo("comment"));
+
+ response = client().prepareSearch("articles")
+ .setQuery(
+ hasChildQuery("comment", matchQuery("message", "fox"), ScoreMode.None).innerHit(
+ new InnerHitBuilder()
+ .addDocValueField("message")
+ .setHighlightBuilder(new HighlightBuilder().field("message"))
+ .setExplain(true).setSize(1)
+ .addScriptField("script", new Script(ScriptType.INLINE, MockScriptEngine.NAME, "5",
+ Collections.emptyMap())),
+ false)
+ ).get();
+ assertNoFailures(response);
+ innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
+ assertThat(innerHits.getHits().length, equalTo(1));
+ assertThat(innerHits.getAt(0).getHighlightFields().get("message").getFragments()[0].string(), equalTo("fox eat quick"));
+ assertThat(innerHits.getAt(0).getExplanation().toString(), containsString("weight(message:fox"));
+ assertThat(innerHits.getAt(0).getFields().get("message").getValue().toString(), equalTo("eat"));
+ assertThat(innerHits.getAt(0).getFields().get("script").getValue().toString(), equalTo("5"));
+ }
+
+ public void testRandomParentChild() throws Exception {
+ assertAcked(prepareCreate("idx")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("parent")
+ .addMapping("child1", "_parent", "type=parent")
+ .addMapping("child2", "_parent", "type=parent")
+ );
+ int numDocs = scaledRandomIntBetween(5, 50);
+ List requestBuilders = new ArrayList<>();
+
+ int child1 = 0;
+ int child2 = 0;
+ int[] child1InnerObjects = new int[numDocs];
+ int[] child2InnerObjects = new int[numDocs];
+ for (int parent = 0; parent < numDocs; parent++) {
+ String parentId = String.format(Locale.ENGLISH, "%03d", parent);
+ requestBuilders.add(client().prepareIndex("idx", "parent", parentId).setSource("{}", XContentType.JSON));
+
+ int numChildDocs = child1InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
+ int limit = child1 + numChildDocs;
+ for (; child1 < limit; child1++) {
+ requestBuilders.add(client().prepareIndex("idx", "child1",
+ String.format(Locale.ENGLISH, "%04d", child1)).setParent(parentId).setSource("{}", XContentType.JSON));
+ }
+ numChildDocs = child2InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
+ limit = child2 + numChildDocs;
+ for (; child2 < limit; child2++) {
+ requestBuilders.add(client().prepareIndex("idx", "child2",
+ String.format(Locale.ENGLISH, "%04d", child2)).setParent(parentId).setSource("{}", XContentType.JSON));
+ }
+ }
+ indexRandom(true, requestBuilders);
+
+ int size = randomIntBetween(0, numDocs);
+ BoolQueryBuilder boolQuery = new BoolQueryBuilder();
+ boolQuery.should(constantScoreQuery(hasChildQuery("child1", matchAllQuery(), ScoreMode.None)
+ .innerHit(new InnerHitBuilder().setName("a")
+ .addSort(new FieldSortBuilder("_uid").order(SortOrder.ASC)).setSize(size), false)));
+ boolQuery.should(constantScoreQuery(hasChildQuery("child2", matchAllQuery(), ScoreMode.None)
+ .innerHit(new InnerHitBuilder().setName("b")
+ .addSort(new FieldSortBuilder("_uid").order(SortOrder.ASC)).setSize(size), false)));
+ SearchResponse searchResponse = client().prepareSearch("idx")
+ .setSize(numDocs)
+ .setTypes("parent")
+ .addSort("_uid", SortOrder.ASC)
+ .setQuery(boolQuery)
+ .get();
+
+ assertNoFailures(searchResponse);
+ assertHitCount(searchResponse, numDocs);
+ assertThat(searchResponse.getHits().getHits().length, equalTo(numDocs));
+
+ int offset1 = 0;
+ int offset2 = 0;
+ for (int parent = 0; parent < numDocs; parent++) {
+ SearchHit searchHit = searchResponse.getHits().getAt(parent);
+ assertThat(searchHit.getType(), equalTo("parent"));
+ assertThat(searchHit.getId(), equalTo(String.format(Locale.ENGLISH, "%03d", parent)));
+ assertThat(searchHit.getShard(), notNullValue());
+
+ SearchHits inner = searchHit.getInnerHits().get("a");
+ assertThat(inner.getTotalHits(), equalTo((long) child1InnerObjects[parent]));
+ for (int child = 0; child < child1InnerObjects[parent] && child < size; child++) {
+ SearchHit innerHit = inner.getAt(child);
+ assertThat(innerHit.getType(), equalTo("child1"));
+ String childId = String.format(Locale.ENGLISH, "%04d", offset1 + child);
+ assertThat(innerHit.getId(), equalTo(childId));
+ assertThat(innerHit.getNestedIdentity(), nullValue());
+ }
+ offset1 += child1InnerObjects[parent];
+
+ inner = searchHit.getInnerHits().get("b");
+ assertThat(inner.getTotalHits(), equalTo((long) child2InnerObjects[parent]));
+ for (int child = 0; child < child2InnerObjects[parent] && child < size; child++) {
+ SearchHit innerHit = inner.getAt(child);
+ assertThat(innerHit.getType(), equalTo("child2"));
+ String childId = String.format(Locale.ENGLISH, "%04d", offset2 + child);
+ assertThat(innerHit.getId(), equalTo(childId));
+ assertThat(innerHit.getNestedIdentity(), nullValue());
+ }
+ offset2 += child2InnerObjects[parent];
+ }
+ }
+
+ public void testInnerHitsOnHasParent() throws Exception {
+ assertAcked(prepareCreate("stack")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("question", "body", "type=text")
+ .addMapping("answer", "_parent", "type=question", "body", "type=text")
+ );
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("stack", "question", "1").setSource("body", "I'm using HTTPS + Basic authentication "
+ + "to protect a resource. How can I throttle authentication attempts to protect against brute force attacks?"));
+ requests.add(client().prepareIndex("stack", "answer", "1").setParent("1").setSource("body",
+ "install fail2ban and enable rules for apache"));
+ requests.add(client().prepareIndex("stack", "question", "2").setSource("body",
+ "I have firewall rules set up and also denyhosts installed.\\ndo I also need to install fail2ban?"));
+ requests.add(client().prepareIndex("stack", "answer", "2").setParent("2").setSource("body",
+ "Denyhosts protects only ssh; Fail2Ban protects all daemons."));
+ indexRandom(true, requests);
+
+ SearchResponse response = client().prepareSearch("stack")
+ .setTypes("answer")
+ .addSort("_uid", SortOrder.ASC)
+ .setQuery(
+ boolQuery()
+ .must(matchQuery("body", "fail2ban"))
+ .must(hasParentQuery("question", matchAllQuery(), false).innerHit(new InnerHitBuilder(), false))
+ ).get();
+ assertNoFailures(response);
+ assertHitCount(response, 2);
+
+ SearchHit searchHit = response.getHits().getAt(0);
+ assertThat(searchHit.getId(), equalTo("1"));
+ assertThat(searchHit.getType(), equalTo("answer"));
+ assertThat(searchHit.getInnerHits().get("question").getTotalHits(), equalTo(1L));
+ assertThat(searchHit.getInnerHits().get("question").getAt(0).getType(), equalTo("question"));
+ assertThat(searchHit.getInnerHits().get("question").getAt(0).getId(), equalTo("1"));
+
+ searchHit = response.getHits().getAt(1);
+ assertThat(searchHit.getId(), equalTo("2"));
+ assertThat(searchHit.getType(), equalTo("answer"));
+ assertThat(searchHit.getInnerHits().get("question").getTotalHits(), equalTo(1L));
+ assertThat(searchHit.getInnerHits().get("question").getAt(0).getType(), equalTo("question"));
+ assertThat(searchHit.getInnerHits().get("question").getAt(0).getId(), equalTo("2"));
+ }
+
+ public void testParentChildMultipleLayers() throws Exception {
+ assertAcked(prepareCreate("articles")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("article", "title", "type=text")
+ .addMapping("comment", "_parent", "type=article", "message", "type=text")
+ .addMapping("remark", "_parent", "type=comment", "message", "type=text")
+ );
+
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("articles", "article", "1").setSource("title", "quick brown fox"));
+ requests.add(client().prepareIndex("articles", "comment", "1").setParent("1").setSource("message", "fox eat quick"));
+ requests.add(client().prepareIndex("articles", "remark", "1").setParent("1").setRouting("1").setSource("message", "good"));
+ requests.add(client().prepareIndex("articles", "article", "2").setSource("title", "big gray elephant"));
+ requests.add(client().prepareIndex("articles", "comment", "2").setParent("2").setSource("message", "elephant captured"));
+ requests.add(client().prepareIndex("articles", "remark", "2").setParent("2").setRouting("2").setSource("message", "bad"));
+ indexRandom(true, requests);
+
+ SearchResponse response = client().prepareSearch("articles")
+ .setQuery(hasChildQuery("comment",
+ hasChildQuery("remark", matchQuery("message", "good"), ScoreMode.None).innerHit(new InnerHitBuilder(), false),
+ ScoreMode.None).innerHit(new InnerHitBuilder(), false))
+ .get();
+
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+ assertSearchHit(response, 1, hasId("1"));
+
+ assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
+ SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
+ assertThat(innerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("1"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
+
+ innerHits = innerHits.getAt(0).getInnerHits().get("remark");
+ assertThat(innerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("1"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("remark"));
+
+ response = client().prepareSearch("articles")
+ .setQuery(hasChildQuery("comment",
+ hasChildQuery("remark", matchQuery("message", "bad"), ScoreMode.None).innerHit(new InnerHitBuilder(), false),
+ ScoreMode.None).innerHit(new InnerHitBuilder(), false))
+ .get();
+
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+ assertSearchHit(response, 1, hasId("2"));
+
+ assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
+ innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
+ assertThat(innerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("2"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("comment"));
+
+ innerHits = innerHits.getAt(0).getInnerHits().get("remark");
+ assertThat(innerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("2"));
+ assertThat(innerHits.getAt(0).getType(), equalTo("remark"));
+ }
+
+ public void testRoyals() throws Exception {
+ assertAcked(
+ prepareCreate("royals")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("king")
+ .addMapping("prince", "_parent", "type=king")
+ .addMapping("duke", "_parent", "type=prince")
+ .addMapping("earl", "_parent", "type=duke")
+ .addMapping("baron", "_parent", "type=earl")
+ );
+
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("royals", "king", "king").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "prince", "prince").setParent("king").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "duke", "duke").setParent("prince").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "earl", "earl1").setParent("duke").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "earl", "earl2").setParent("duke").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "earl", "earl3").setParent("duke").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "earl", "earl4").setParent("duke").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "baron", "baron1").setParent("earl1").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "baron", "baron2").setParent("earl2").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "baron", "baron3").setParent("earl3").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("royals", "baron", "baron4").setParent("earl4").setRouting("king")
+ .setSource("{}", XContentType.JSON));
+ indexRandom(true, requests);
+
+ SearchResponse response = client().prepareSearch("royals")
+ .setTypes("duke")
+ .setQuery(boolQuery()
+ .filter(hasParentQuery("prince",
+ hasParentQuery("king", matchAllQuery(), false).innerHit(new InnerHitBuilder().setName("kings"), false),
+ false).innerHit(new InnerHitBuilder().setName("princes"), false)
+ )
+ .filter(hasChildQuery("earl",
+ hasChildQuery("baron", matchAllQuery(), ScoreMode.None)
+ .innerHit(new InnerHitBuilder().setName("barons"), false),
+ ScoreMode.None).innerHit(new InnerHitBuilder()
+ .addSort(SortBuilders.fieldSort("_uid").order(SortOrder.ASC))
+ .setName("earls")
+ .setSize(4), false)
+ )
+ )
+ .get();
+ assertHitCount(response, 1);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("duke"));
+
+ SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("earls");
+ assertThat(innerHits.getTotalHits(), equalTo(4L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("earl1"));
+ assertThat(innerHits.getAt(1).getId(), equalTo("earl2"));
+ assertThat(innerHits.getAt(2).getId(), equalTo("earl3"));
+ assertThat(innerHits.getAt(3).getId(), equalTo("earl4"));
+
+ SearchHits innerInnerHits = innerHits.getAt(0).getInnerHits().get("barons");
+ assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron1"));
+
+ innerInnerHits = innerHits.getAt(1).getInnerHits().get("barons");
+ assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron2"));
+
+ innerInnerHits = innerHits.getAt(2).getInnerHits().get("barons");
+ assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron3"));
+
+ innerInnerHits = innerHits.getAt(3).getInnerHits().get("barons");
+ assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerInnerHits.getAt(0).getId(), equalTo("baron4"));
+
+ innerHits = response.getHits().getAt(0).getInnerHits().get("princes");
+ assertThat(innerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerHits.getAt(0).getId(), equalTo("prince"));
+
+ innerInnerHits = innerHits.getAt(0).getInnerHits().get("kings");
+ assertThat(innerInnerHits.getTotalHits(), equalTo(1L));
+ assertThat(innerInnerHits.getAt(0).getId(), equalTo("king"));
+ }
+
+ public void testMatchesQueriesParentChildInnerHits() throws Exception {
+ assertAcked(prepareCreate("index")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("child", "_parent", "type=parent"));
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("index", "parent", "1").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("index", "child", "1").setParent("1").setSource("field", "value1"));
+ requests.add(client().prepareIndex("index", "child", "2").setParent("1").setSource("field", "value2"));
+ requests.add(client().prepareIndex("index", "parent", "2").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("index", "child", "3").setParent("2").setSource("field", "value1"));
+ indexRandom(true, requests);
+
+ SearchResponse response = client().prepareSearch("index")
+ .setQuery(hasChildQuery("child", matchQuery("field", "value1").queryName("_name1"), ScoreMode.None)
+ .innerHit(new InnerHitBuilder(), false))
+ .addSort("_uid", SortOrder.ASC)
+ .get();
+ assertHitCount(response, 2);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getTotalHits(), equalTo(1L));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name1"));
+
+ assertThat(response.getHits().getAt(1).getId(), equalTo("2"));
+ assertThat(response.getHits().getAt(1).getInnerHits().get("child").getTotalHits(), equalTo(1L));
+ assertThat(response.getHits().getAt(1).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
+ assertThat(response.getHits().getAt(1).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name1"));
+
+ QueryBuilder query = hasChildQuery("child", matchQuery("field", "value2").queryName("_name2"), ScoreMode.None)
+ .innerHit(new InnerHitBuilder(), false);
+ response = client().prepareSearch("index")
+ .setQuery(query)
+ .addSort("_uid", SortOrder.ASC)
+ .get();
+ assertHitCount(response, 1);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getTotalHits(), equalTo(1L));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries().length, equalTo(1));
+ assertThat(response.getHits().getAt(0).getInnerHits().get("child").getAt(0).getMatchedQueries()[0], equalTo("_name2"));
+ }
+
+ public void testDontExplode() throws Exception {
+ assertAcked(prepareCreate("index1")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("child", "_parent", "type=parent"));
+ List requests = new ArrayList<>();
+ requests.add(client().prepareIndex("index1", "parent", "1").setSource("{}", XContentType.JSON));
+ requests.add(client().prepareIndex("index1", "child", "1").setParent("1").setSource("field", "value1"));
+ indexRandom(true, requests);
+
+ QueryBuilder query = hasChildQuery("child", matchQuery("field", "value1"), ScoreMode.None)
+ .innerHit(new InnerHitBuilder().setSize(ArrayUtil.MAX_ARRAY_LENGTH - 1), false);
+ SearchResponse response = client().prepareSearch("index1")
+ .setQuery(query)
+ .get();
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+
+ assertAcked(prepareCreate("index2").addMapping("type", "nested", "type=nested"));
+ client().prepareIndex("index2", "type", "1").setSource(jsonBuilder().startObject()
+ .startArray("nested")
+ .startObject()
+ .field("field", "value1")
+ .endObject()
+ .endArray()
+ .endObject())
+ .setRefreshPolicy(IMMEDIATE)
+ .get();
+
+ query = nestedQuery("nested", matchQuery("nested.field", "value1"), ScoreMode.Avg)
+ .innerHit(new InnerHitBuilder().setSize(ArrayUtil.MAX_ARRAY_LENGTH - 1), false);
+ response = client().prepareSearch("index2")
+ .setQuery(query)
+ .get();
+ assertNoFailures(response);
+ assertHitCount(response, 1);
+ }
+
+ public void testNestedInnerHitWrappedInParentChildInnerhit() throws Exception {
+ assertAcked(prepareCreate("test")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("child_type", "_parent", "type=parent_type", "nested_type", "type=nested"));
+ client().prepareIndex("test", "parent_type", "1").setSource("key", "value").get();
+ client().prepareIndex("test", "child_type", "2").setParent("1").setSource("nested_type", Collections.singletonMap("key", "value"))
+ .get();
+ refresh();
+ SearchResponse response = client().prepareSearch("test")
+ .setQuery(boolQuery().must(matchQuery("key", "value"))
+ .should(hasChildQuery("child_type", nestedQuery("nested_type", matchAllQuery(), ScoreMode.None)
+ .innerHit(new InnerHitBuilder(), false), ScoreMode.None).innerHit(new InnerHitBuilder(), false)))
+ .get();
+ assertHitCount(response, 1);
+ SearchHit hit = response.getHits().getAt(0);
+ assertThat(hit.getInnerHits().get("child_type").getAt(0).field("_parent").getValue(), equalTo("1"));
+ assertThat(hit.getInnerHits().get("child_type").getAt(0).getInnerHits().get("nested_type").getAt(0).field("_parent"), nullValue());
+ }
+
+ public void testInnerHitsWithIgnoreUnmapped() throws Exception {
+ assertAcked(prepareCreate("index1")
+ .setSettings("index.mapping.single_type", false)
+ .addMapping("parent_type", "nested_type", "type=nested")
+ .addMapping("child_type", "_parent", "type=parent_type")
+ );
+ createIndex("index2");
+ client().prepareIndex("index1", "parent_type", "1").setSource("nested_type", Collections.singletonMap("key", "value")).get();
+ client().prepareIndex("index1", "child_type", "2").setParent("1").setSource("{}", XContentType.JSON).get();
+ client().prepareIndex("index2", "type", "3").setSource("key", "value").get();
+ refresh();
+
+ SearchResponse response = client().prepareSearch("index1", "index2")
+ .setQuery(boolQuery()
+ .should(hasChildQuery("child_type", matchAllQuery(), ScoreMode.None).ignoreUnmapped(true)
+ .innerHit(new InnerHitBuilder(), true))
+ .should(termQuery("key", "value"))
+ )
+ .get();
+ assertNoFailures(response);
+ assertHitCount(response, 2);
+ assertSearchHits(response, "1", "3");
+ }
+}
diff --git a/modules/parent-join/src/test/resources/rest-api-spec/test/10_basic.yaml b/modules/parent-join/src/test/resources/rest-api-spec/test/10_basic.yaml
new file mode 100644
index 00000000000..f5a58080129
--- /dev/null
+++ b/modules/parent-join/src/test/resources/rest-api-spec/test/10_basic.yaml
@@ -0,0 +1,48 @@
+setup:
+ - do:
+ indices.create:
+ index: test
+ body:
+ settings:
+ mapping.single_type: false
+ mappings:
+ type_2: {}
+ type_3:
+ _parent:
+ type: type_2
+
+---
+"Parent/child inner hits":
+ - skip:
+ version: " - 5.99.99"
+ reason: mapping.single_type was added in 6.0
+
+ - do:
+ index:
+ index: test
+ type: type_2
+ id: 1
+ body: {"foo": "bar"}
+
+ - do:
+ index:
+ index: test
+ type: type_3
+ id: 1
+ parent: 1
+ body: {"bar": "baz"}
+
+ - do:
+ indices.refresh: {}
+
+ - do:
+ search:
+ body: { "query" : { "has_child" : { "type" : "type_3", "query" : { "match_all" : {} }, "inner_hits" : {} } } }
+ - match: { hits.total: 1 }
+ - match: { hits.hits.0._index: "test" }
+ - match: { hits.hits.0._type: "type_2" }
+ - match: { hits.hits.0._id: "1" }
+ - is_false: hits.hits.0.inner_hits.type_3.hits.hits.0._index
+ - match: { hits.hits.0.inner_hits.type_3.hits.hits.0._type: "type_3" }
+ - match: { hits.hits.0.inner_hits.type_3.hits.hits.0._id: "1" }
+ - is_false: hits.hits.0.inner_hits.type_3.hits.hits.0._nested
diff --git a/modules/percolator/build.gradle b/modules/percolator/build.gradle
index 60fb82bdf4e..cf55368861a 100644
--- a/modules/percolator/build.gradle
+++ b/modules/percolator/build.gradle
@@ -23,5 +23,9 @@ esplugin {
hasClientJar = true
}
+dependencies {
+ // for testing hasChild and hasParent rejections
+ testCompile project(path: ':modules:parent-join', configuration: 'runtime')
+}
compileJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes"
compileTestJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes"
diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
index f33aca55bc1..1865f68158e 100644
--- a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
+++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java
@@ -57,8 +57,6 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostingQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
-import org.elasticsearch.index.query.HasChildQueryBuilder;
-import org.elasticsearch.index.query.HasParentQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
@@ -372,15 +370,16 @@ public class PercolatorFieldMapper extends FieldMapper {
return CONTENT_TYPE;
}
+
/**
* Fails if a percolator contains an unsupported query. The following queries are not supported:
* 1) a has_child query
* 2) a has_parent query
*/
static void verifyQuery(QueryBuilder queryBuilder) {
- if (queryBuilder instanceof HasChildQueryBuilder) {
+ if (queryBuilder.getName().equals("has_child")) {
throw new IllegalArgumentException("the [has_child] query is unsupported inside a percolator query");
- } else if (queryBuilder instanceof HasParentQueryBuilder) {
+ } else if (queryBuilder.getName().equals("has_parent")) {
throw new IllegalArgumentException("the [has_parent] query is unsupported inside a percolator query");
} else if (queryBuilder instanceof BoolQueryBuilder) {
BoolQueryBuilder boolQueryBuilder = (BoolQueryBuilder) queryBuilder;
diff --git a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
index ae585dc9dc7..5a150349ed2 100644
--- a/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
+++ b/modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorFieldMapperTests.java
@@ -52,13 +52,10 @@ import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.SourceToParse;
-import org.elasticsearch.index.mapper.MapperService.MergeReason;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostingQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
-import org.elasticsearch.index.query.HasChildQueryBuilder;
-import org.elasticsearch.index.query.HasParentQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
@@ -67,6 +64,9 @@ import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.RandomScoreFunctionBuilder;
import org.elasticsearch.indices.TermsLookup;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.join.query.HasChildQueryBuilder;
+import org.elasticsearch.join.query.HasParentQueryBuilder;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
@@ -109,7 +109,7 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
@Override
protected Collection> getPlugins() {
- return pluginList(InternalSettingsPlugin.class, PercolatorPlugin.class, FoolMeScriptPlugin.class);
+ return pluginList(InternalSettingsPlugin.class, PercolatorPlugin.class, FoolMeScriptPlugin.class, ParentJoinPlugin.class);
}
@Before
diff --git a/modules/reindex/build.gradle b/modules/reindex/build.gradle
index eba8b964617..b636c46d3af 100644
--- a/modules/reindex/build.gradle
+++ b/modules/reindex/build.gradle
@@ -39,6 +39,8 @@ dependencies {
compile "org.elasticsearch.client:rest:${version}"
// for http - testing reindex from remote
testCompile project(path: ':modules:transport-netty4', configuration: 'runtime')
+ // for parent/child testing
+ testCompile project(path: ':modules:parent-join', configuration: 'runtime')
}
dependencyLicenses {
diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java
index d0eb1dcd75e..8c4135f1f26 100644
--- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java
+++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexParentChildTests.java
@@ -22,9 +22,16 @@ package org.elasticsearch.index.reindex;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.join.ParentJoinPlugin;
+import org.elasticsearch.plugins.Plugin;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
-import static org.elasticsearch.index.query.QueryBuilders.hasParentQuery;
import static org.elasticsearch.index.query.QueryBuilders.idsQuery;
+import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits;
import static org.hamcrest.Matchers.containsString;
@@ -40,6 +47,23 @@ public class ReindexParentChildTests extends ReindexTestCase {
QueryBuilder findsCity;
QueryBuilder findsNeighborhood;
+ @Override
+ protected boolean ignoreExternalCluster() {
+ return true;
+ }
+
+ @Override
+ protected Collection> nodePlugins() {
+ final List> plugins = new ArrayList<>(super.nodePlugins());
+ plugins.add(ParentJoinPlugin.class);
+ return Collections.unmodifiableList(plugins);
+ }
+
+ @Override
+ protected Collection> transportClientPlugins() {
+ return nodePlugins();
+ }
+
public void testParentChild() throws Exception {
createParentChildIndex("source");
createParentChildIndex("dest");
diff --git a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml
index b30f263e869..32de51d022a 100644
--- a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml
+++ b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml
@@ -158,85 +158,6 @@
metric: search
- match: {indices.source.total.search.open_contexts: 0}
----
-"Reindex from remote with parent/child":
- - do:
- indices.create:
- index: source
- body:
- settings:
- mapping.single_type: false
- mappings:
- foo: {}
- bar:
- _parent:
- type: foo
- - do:
- indices.create:
- index: dest
- body:
- settings:
- mapping.single_type: false
- mappings:
- foo: {}
- bar:
- _parent:
- type: foo
- - do:
- index:
- index: source
- type: foo
- id: 1
- body: { "text": "test" }
- - do:
- index:
- index: source
- type: bar
- id: 1
- parent: 1
- body: { "text": "test2" }
- - do:
- indices.refresh: {}
-
- # Fetch the http host. We use the host of the master because we know there will always be a master.
- - do:
- cluster.state: {}
- - set: { master_node: master }
- - do:
- nodes.info:
- metric: [ http ]
- - is_true: nodes.$master.http.publish_address
- - set: {nodes.$master.http.publish_address: host}
- - do:
- reindex:
- refresh: true
- body:
- source:
- remote:
- host: http://${host}
- index: source
- dest:
- index: dest
- - match: {created: 2}
-
- - do:
- search:
- index: dest
- body:
- query:
- has_parent:
- parent_type: foo
- query:
- match:
- text: test
- - match: {hits.total: 1}
-
- # Make sure reindex closed all the scroll contexts
- - do:
- indices.stats:
- index: source
- metric: search
- - match: {indices.source.total.search.open_contexts: 0}
---
"Reindex from remote with timeouts":
diff --git a/qa/smoke-test-reindex-with-painless/build.gradle b/qa/smoke-test-reindex-with-all-modules/build.gradle
similarity index 89%
rename from qa/smoke-test-reindex-with-painless/build.gradle
rename to qa/smoke-test-reindex-with-all-modules/build.gradle
index b32f4ee80be..cab01cb9412 100644
--- a/qa/smoke-test-reindex-with-painless/build.gradle
+++ b/qa/smoke-test-reindex-with-all-modules/build.gradle
@@ -22,4 +22,6 @@ apply plugin: 'elasticsearch.rest-test'
integTestCluster {
setting 'script.max_compilations_per_minute', '1000'
-}
+ // Whitelist reindexing from the local node so we can test it.
+ setting 'reindex.remote.whitelist', '127.0.0.1:*'
+}
\ No newline at end of file
diff --git a/qa/smoke-test-reindex-with-painless/src/test/java/org/elasticsearch/smoketest/SmokeTestReindexWithPainlessClientYamlTestSuiteIT.java b/qa/smoke-test-reindex-with-all-modules/src/test/java/org/elasticsearch/smoketest/SmokeTestReindexWithPainlessClientYamlTestSuiteIT.java
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/java/org/elasticsearch/smoketest/SmokeTestReindexWithPainlessClientYamlTestSuiteIT.java
rename to qa/smoke-test-reindex-with-all-modules/src/test/java/org/elasticsearch/smoketest/SmokeTestReindexWithPainlessClientYamlTestSuiteIT.java
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/10_script.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/10_script.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/10_script.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/10_script.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/20_broken.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/20_broken.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/20_broken.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/20_broken.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/30_timeout.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/30_timeout.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/30_timeout.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/30_timeout.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/40_search_failures.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/40_search_failures.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/reindex/40_search_failures.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/40_search_failures.yaml
diff --git a/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/50_reindex_with_parentchild.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/50_reindex_with_parentchild.yaml
new file mode 100644
index 00000000000..81e142c9195
--- /dev/null
+++ b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/reindex/50_reindex_with_parentchild.yaml
@@ -0,0 +1,79 @@
+---
+"Reindex from remote with parent/child":
+ - do:
+ indices.create:
+ index: source
+ body:
+ settings:
+ mapping.single_type: false
+ mappings:
+ foo: {}
+ bar:
+ _parent:
+ type: foo
+ - do:
+ indices.create:
+ index: dest
+ body:
+ settings:
+ mapping.single_type: false
+ mappings:
+ foo: {}
+ bar:
+ _parent:
+ type: foo
+ - do:
+ index:
+ index: source
+ type: foo
+ id: 1
+ body: { "text": "test" }
+ - do:
+ index:
+ index: source
+ type: bar
+ id: 1
+ parent: 1
+ body: { "text": "test2" }
+ - do:
+ indices.refresh: {}
+
+ # Fetch the http host. We use the host of the master because we know there will always be a master.
+ - do:
+ cluster.state: {}
+ - set: { master_node: master }
+ - do:
+ nodes.info:
+ metric: [ http ]
+ - is_true: nodes.$master.http.publish_address
+ - set: {nodes.$master.http.publish_address: host}
+ - do:
+ reindex:
+ refresh: true
+ body:
+ source:
+ remote:
+ host: http://${host}
+ index: source
+ dest:
+ index: dest
+ - match: {created: 2}
+
+ - do:
+ search:
+ index: dest
+ body:
+ query:
+ has_parent:
+ parent_type: foo
+ query:
+ match:
+ text: test
+ - match: {hits.total: 1}
+
+ # Make sure reindex closed all the scroll contexts
+ - do:
+ indices.stats:
+ index: source
+ metric: search
+ - match: {indices.source.total.search.open_contexts: 0}
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/10_script.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/10_script.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/10_script.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/10_script.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/20_broken.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/20_broken.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/20_broken.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/20_broken.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/30_timeout.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/30_timeout.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/30_timeout.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/30_timeout.yaml
diff --git a/qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/40_search_failure.yaml b/qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/40_search_failure.yaml
similarity index 100%
rename from qa/smoke-test-reindex-with-painless/src/test/resources/rest-api-spec/test/update_by_query/40_search_failure.yaml
rename to qa/smoke-test-reindex-with-all-modules/src/test/resources/rest-api-spec/test/update_by_query/40_search_failure.yaml
diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.inner_hits/10_basic.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.inner_hits/10_basic.yaml
index d50c3dcb574..45524366342 100644
--- a/rest-api-spec/src/main/resources/rest-api-spec/test/search.inner_hits/10_basic.yaml
+++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.inner_hits/10_basic.yaml
@@ -11,10 +11,6 @@ setup:
properties:
nested_field:
type: nested
- type_2: {}
- type_3:
- _parent:
- type: type_2
---
"Nested inner hits":
@@ -47,38 +43,3 @@ setup:
- match: { hits.hits.0.inner_hits.nested_field.hits.hits.0._nested.offset: 0 }
- is_false: hits.hits.0.inner_hits.nested_field.hits.hits.0._nested.child
----
-"Parent/child inner hits":
- - skip:
- version: " - 5.99.99"
- reason: mapping.single_type was added in 6.0
-
- - do:
- index:
- index: test
- type: type_2
- id: 1
- body: {"foo": "bar"}
-
- - do:
- index:
- index: test
- type: type_3
- id: 1
- parent: 1
- body: {"bar": "baz"}
-
- - do:
- indices.refresh: {}
-
- - do:
- search:
- body: { "query" : { "has_child" : { "type" : "type_3", "query" : { "match_all" : {} }, "inner_hits" : {} } } }
- - match: { hits.total: 1 }
- - match: { hits.hits.0._index: "test" }
- - match: { hits.hits.0._type: "type_2" }
- - match: { hits.hits.0._id: "1" }
- - is_false: hits.hits.0.inner_hits.type_3.hits.hits.0._index
- - match: { hits.hits.0.inner_hits.type_3.hits.hits.0._type: "type_3" }
- - match: { hits.hits.0.inner_hits.type_3.hits.hits.0._id: "1" }
- - is_false: hits.hits.0.inner_hits.type_3.hits.hits.0._nested
diff --git a/settings.gradle b/settings.gradle
index 7acedd9c98b..b2ef30b99dd 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -34,6 +34,7 @@ List projects = [
'modules:lang-expression',
'modules:lang-mustache',
'modules:lang-painless',
+ 'modules:parent-join',
'modules:percolator',
'modules:reindex',
'modules:repository-url',
@@ -72,7 +73,7 @@ List projects = [
'qa:smoke-test-ingest-disabled',
'qa:smoke-test-multinode',
'qa:smoke-test-plugins',
- 'qa:smoke-test-reindex-with-painless',
+ 'qa:smoke-test-reindex-with-all-modules',
'qa:smoke-test-tribe-node',
'qa:vagrant',
'qa:wildfly'
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java b/test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java
similarity index 100%
rename from core/src/test/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java
rename to test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java b/test/framework/src/main/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
similarity index 95%
rename from core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
rename to test/framework/src/main/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
index c76d1a5f0dd..e27199918f4 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
@@ -33,6 +33,9 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.indices.IndicesModule;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.plugins.PluginsService;
+import org.elasticsearch.plugins.SearchPlugin;
import org.elasticsearch.search.SearchModule;
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
import org.elasticsearch.test.AbstractQueryTestCase;
@@ -40,6 +43,7 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -66,6 +70,10 @@ public abstract class BaseAggregationTestCase> getPlugins() {
+ return Collections.emptyList();
+ }
+
/**
* Setup for the whole base test class.
*/
@@ -77,7 +85,8 @@ public abstract class BaseAggregationTestCase entries = new ArrayList<>();
entries.addAll(indicesModule.getNamedWriteables());
entries.addAll(searchModule.getNamedWriteables());
@@ -145,7 +154,6 @@ public abstract class BaseAggregationTestCase