Improve `has_child` filter / query performance (#2251) Added a new has_child filter implementation, that works _uid based instead of bitset based. This implementation is about ~2 till ~6 times (depending on the query) faster than the already existing bitset based implementation.

This commit is contained in:
Martijn van Groningen 2012-09-13 15:47:24 +02:00 committed by Shay Banon
parent 4dddeeb30c
commit 3cd54fc4ee
11 changed files with 319 additions and 117 deletions

View File

@ -36,6 +36,8 @@ public class HasChildFilterBuilder extends BaseFilterBuilder {
private String filterName;
private String executionType;
public HasChildFilterBuilder(String type, QueryBuilder queryBuilder) {
this.childType = type;
this.queryBuilder = queryBuilder;
@ -54,18 +56,31 @@ public class HasChildFilterBuilder extends BaseFilterBuilder {
return this;
}
/**
* Expert: Sets the low level child to parent filtering implementation. Can be: 'bitset' or 'uid'
*
* This option is experimental and will be removed.
*/
public HasChildFilterBuilder executionType(String executionType) {
this.executionType = executionType;
return this;
}
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(HasChildFilterParser.NAME);
builder.field("query");
queryBuilder.toXContent(builder, params);
builder.field("type", childType);
builder.field("child_type", childType);
if (scope != null) {
builder.field("_scope", scope);
}
if (filterName != null) {
builder.field("_name", filterName);
}
if (executionType != null) {
builder.field("execution_type", executionType);
}
builder.endObject();
}
}

View File

@ -56,6 +56,7 @@ public class HasChildFilterParser implements FilterParser {
String childType = null;
String scope = null;
String executionType = "uid";
String filterName = null;
String currentFieldName = null;
XContentParser.Token token;
@ -77,12 +78,14 @@ public class HasChildFilterParser implements FilterParser {
throw new QueryParsingException(parseContext.index(), "[has_child] filter does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if ("type".equals(currentFieldName)) {
if ("type".equals(currentFieldName) || "child_type".equals(currentFieldName) || "childType".equals(currentFieldName)) {
childType = parser.text();
} else if ("_scope".equals(currentFieldName)) {
scope = parser.text();
} else if ("_name".equals(currentFieldName)) {
filterName = parser.text();
} else if ("execution_type".equals(currentFieldName) || "executionType".equals(currentFieldName)) {// This option is experimental and will most likely be removed.
executionType = parser.text();
} else {
throw new QueryParsingException(parseContext.index(), "[has_child] filter does not support [" + currentFieldName + "]");
}
@ -112,7 +115,7 @@ public class HasChildFilterParser implements FilterParser {
SearchContext searchContext = SearchContext.current();
HasChildFilter childFilter = new HasChildFilter(query, scope, childType, parentType, searchContext);
HasChildFilter childFilter = HasChildFilter.create(query, scope, parentType, childType, searchContext, executionType);
searchContext.addScopePhase(childFilter);
if (filterName != null) {

View File

@ -36,6 +36,8 @@ public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQ
private float boost = 1.0f;
private String executionType;
public HasChildQueryBuilder(String type, QueryBuilder queryBuilder) {
this.childType = type;
this.queryBuilder = queryBuilder;
@ -59,18 +61,31 @@ public class HasChildQueryBuilder extends BaseQueryBuilder implements BoostableQ
return this;
}
/**
* Expert: Sets the low level child to parent filtering implementation. Can be: 'bitset' or 'uid'
*
* This option is experimental and will be removed.
*/
public HasChildQueryBuilder executionType(String executionType) {
this.executionType = executionType;
return this;
}
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(HasChildQueryParser.NAME);
builder.field("query");
queryBuilder.toXContent(builder, params);
builder.field("type", childType);
builder.field("child_type", childType);
if (scope != null) {
builder.field("_scope", scope);
}
if (boost != 1.0f) {
builder.field("boost", boost);
}
if (executionType != null) {
builder.field("execution_type", executionType);
}
builder.endObject();
}
}

View File

@ -57,6 +57,7 @@ public class HasChildQueryParser implements QueryParser {
String childType = null;
String scope = null;
String executionType = "uid";
String currentFieldName = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@ -77,12 +78,14 @@ public class HasChildQueryParser implements QueryParser {
throw new QueryParsingException(parseContext.index(), "[has_child] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if ("type".equals(currentFieldName)) {
if ("type".equals(currentFieldName) || "child_type".equals(currentFieldName) || "childType".equals(currentFieldName)) {
childType = parser.text();
} else if ("_scope".equals(currentFieldName)) {
scope = parser.text();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("execution_type".equals(currentFieldName) || "executionType".equals(currentFieldName)) {// This option is experimental and will most likely be removed.
executionType = parser.text();
} else {
throw new QueryParsingException(parseContext.index(), "[has_child] query does not support [" + currentFieldName + "]");
}
@ -112,7 +115,7 @@ public class HasChildQueryParser implements QueryParser {
query = new FilteredQuery(query, parseContext.cacheFilter(childDocMapper.typeFilter(), null));
SearchContext searchContext = SearchContext.current();
HasChildFilter childFilter = new HasChildFilter(query, scope, childType, parentType, searchContext);
HasChildFilter childFilter = HasChildFilter.create(query, scope, parentType, childType, searchContext, executionType);
// we don't need DeletionAwareConstantScore, since we filter deleted parent docs in the filter
ConstantScoreQuery childQuery = new ConstantScoreQuery(childFilter);
childQuery.setBoost(boost);

View File

@ -54,7 +54,7 @@ public class HasParentFilterBuilder extends BaseFilterBuilder {
}
/**
* Expert: Sets the low level parent to child filtering implementation. Can be: 'indirect' or 'uid'
* Expert: Sets the low level parent to child filtering implementation. Can be: 'bitset' or 'uid'
*
* This option is experimental and will be removed.
*/

View File

@ -85,7 +85,6 @@ public class HasParentFilterParser implements FilterParser {
scope = parser.text();
} else if ("_name".equals(currentFieldName)) {
filterName = parser.text();
// TODO: change to execution_type
} else if ("execution_type".equals(currentFieldName) || "executionType".equals(currentFieldName)) { // This option is experimental and will most likely be removed.
executionType = parser.text();
} else {

View File

@ -19,12 +19,19 @@
package org.elasticsearch.index.search.child;
import gnu.trove.set.hash.THashSet;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.FixedBitSet;
import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.common.CacheRecycler;
import org.elasticsearch.common.bytes.HashedBytesArray;
import org.elasticsearch.common.lucene.docset.GetDocSet;
import org.elasticsearch.common.lucene.search.NoopCollector;
import org.elasticsearch.index.cache.id.IdReaderTypeCache;
import org.elasticsearch.search.internal.ScopePhase;
import org.elasticsearch.search.internal.SearchContext;
@ -34,68 +41,150 @@ import java.util.Map;
/**
*
*/
public class HasChildFilter extends Filter implements ScopePhase.CollectorPhase {
public abstract class HasChildFilter extends Filter implements ScopePhase.CollectorPhase {
private Query query;
final Query childQuery;
final String scope;
final String parentType;
final String childType;
final SearchContext searchContext;
private String scope;
private String parentType;
private String childType;
private final SearchContext searchContext;
private Map<Object, FixedBitSet> parentDocs;
public HasChildFilter(Query query, String scope, String childType, String parentType, SearchContext searchContext) {
this.query = query;
this.scope = scope;
protected HasChildFilter(Query childQuery, String scope, String parentType, String childType, SearchContext searchContext) {
this.searchContext = searchContext;
this.parentType = parentType;
this.childType = childType;
this.searchContext = searchContext;
this.scope = scope;
this.childQuery = childQuery;
}
@Override
public Query query() {
return query;
return childQuery;
}
@Override
public boolean requiresProcessing() {
return parentDocs == null;
}
@Override
public Collector collector() {
return new ChildCollector(parentType, searchContext);
}
@Override
public void processCollector(Collector collector) {
this.parentDocs = ((ChildCollector) collector).parentDocs();
}
@Override
public String scope() {
return this.scope;
}
@Override
public void clear() {
parentDocs = null;
}
@Override
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
// ok to return null
return parentDocs.get(reader.getCoreCacheKey());
return scope;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("child_filter[").append(childType).append("/").append(parentType).append("](").append(query).append(')');
sb.append("child_filter[").append(childType).append("/").append(parentType).append("](").append(childQuery).append(')');
return sb.toString();
}
public static HasChildFilter create(Query childQuery, String scope, String parentType, String childType, SearchContext searchContext, String executionType) {
// This mechanism is experimental and will most likely be removed.
if ("bitset".equals(executionType)) {
return new Bitset(childQuery, scope, parentType, childType, searchContext);
} else if ("uid".endsWith(executionType)) {
return new Uid(childQuery, scope, parentType, childType, searchContext);
}
throw new ElasticSearchIllegalStateException("Illegal has_child execution type: " + executionType);
}
static class Bitset extends HasChildFilter {
private Map<Object, FixedBitSet> parentDocs;
public Bitset(Query childQuery, String scope, String parentType, String childType, SearchContext searchContext) {
super(childQuery, scope, parentType, childType, searchContext);
}
public boolean requiresProcessing() {
return parentDocs == null;
}
public Collector collector() {
return new ChildCollector(parentType, searchContext);
}
public void processCollector(Collector collector) {
this.parentDocs = ((ChildCollector) collector).parentDocs();
}
public void clear() {
parentDocs = null;
}
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
// ok to return null
return parentDocs.get(reader.getCoreCacheKey());
}
}
static class Uid extends HasChildFilter {
THashSet<HashedBytesArray> collectedUids;
Uid(Query childQuery, String scope, String parentType, String childType, SearchContext searchContext) {
super(childQuery, scope, parentType, childType, searchContext);
}
public boolean requiresProcessing() {
return collectedUids == null;
}
public Collector collector() {
collectedUids = CacheRecycler.popHashSet();
return new UidCollector(parentType, searchContext, collectedUids);
}
public void processCollector(Collector collector) {
collectedUids = ((UidCollector) collector).collectedUids;
}
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
IdReaderTypeCache idReaderTypeCache = searchContext.idCache().reader(reader).type(parentType);
return new ParentDocSet(reader, collectedUids, idReaderTypeCache);
}
public void clear() {
CacheRecycler.pushHashSet(collectedUids);
collectedUids = null;
}
static class ParentDocSet extends GetDocSet {
final IndexReader reader;
final THashSet<HashedBytesArray> parents;
final IdReaderTypeCache typeCache;
ParentDocSet(IndexReader reader, THashSet<HashedBytesArray> parents, IdReaderTypeCache typeCache) {
super(reader.maxDoc());
this.reader = reader;
this.parents = parents;
this.typeCache = typeCache;
}
public boolean get(int doc) {
return !reader.isDeleted(doc) && parents.contains(typeCache.idByDoc(doc));
}
}
static class UidCollector extends NoopCollector {
final String parentType;
final SearchContext context;
final THashSet<HashedBytesArray> collectedUids;
private IdReaderTypeCache typeCache;
UidCollector(String parentType, SearchContext context, THashSet<HashedBytesArray> collectedUids) {
this.parentType = parentType;
this.context = context;
this.collectedUids = collectedUids;
}
@Override
public void collect(int doc) throws IOException {
collectedUids.add(typeCache.parentIdByDoc(doc));
}
@Override
public void setNextReader(IndexReader reader, int docBase) throws IOException {
typeCache = context.idCache().reader(reader).type(parentType);
}
}
}
}

View File

@ -29,7 +29,6 @@ import org.elasticsearch.common.bytes.HashedBytesArray;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.lucene.docset.GetDocSet;
import org.elasticsearch.common.lucene.search.NoopCollector;
import org.elasticsearch.common.trove.ExtTHashMap;
import org.elasticsearch.index.cache.id.IdReaderTypeCache;
import org.elasticsearch.search.internal.ScopePhase;
import org.elasticsearch.search.internal.SearchContext;
@ -44,13 +43,13 @@ import static com.google.common.collect.Maps.newHashMap;
*/
public abstract class HasParentFilter extends Filter implements ScopePhase.CollectorPhase {
final Query query;
final Query parentQuery;
final String scope;
final String parentType;
final SearchContext context;
HasParentFilter(Query query, String scope, String parentType, SearchContext context) {
this.query = query;
HasParentFilter(Query parentQuery, String scope, String parentType, SearchContext context) {
this.parentQuery = parentQuery;
this.scope = scope;
this.parentType = parentType;
this.context = context;
@ -61,24 +60,31 @@ public abstract class HasParentFilter extends Filter implements ScopePhase.Colle
}
public Query query() {
return query;
return parentQuery;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("parent_filter[").append(parentType).append("](").append(query()).append(')');
return sb.toString();
}
public static HasParentFilter create(String executionType, Query query, String scope, String parentType, SearchContext context) {
// This mechanism is experimental and will most likely be removed.
if ("indirect".equals(executionType)) {
return new InDirect(query, scope, parentType, context);
if ("bitset".equals(executionType)) {
return new Bitset(query, scope, parentType, context);
} else if ("uid".equals(executionType)) {
return new UidParentFilter(query, scope, parentType, context);
return new Uid(query, scope, parentType, context);
}
throw new ElasticSearchIllegalStateException("Illegal has_parent execution type: " + executionType);
}
static class UidParentFilter extends HasParentFilter {
static class Uid extends HasParentFilter {
THashSet<HashedBytesArray> parents;
UidParentFilter(Query query, String scope, String parentType, SearchContext context) {
Uid(Query query, String scope, String parentType, SearchContext context) {
super(query, scope, parentType, context);
}
@ -149,11 +155,11 @@ public abstract class HasParentFilter extends Filter implements ScopePhase.Colle
}
static class InDirect extends HasParentFilter {
static class Bitset extends HasParentFilter {
Map<Object, FixedBitSet> parentDocs;
InDirect(Query query, String scope, String parentType, SearchContext context) {
Bitset(Query query, String scope, String parentType, SearchContext context) {
super(query, scope, parentType, context);
}

View File

@ -136,32 +136,61 @@ public class ChildSearchBenchmark {
}
System.out.println("--> Just Child Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
System.out.println("--> Running has_child query");
// run parent child constant query
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch().setQuery(hasChildQuery("child", termQuery("tag", "tag1"))).execute().actionGet();
if (searchResponse.failedShards() > 0) {
System.err.println("Search Failures " + Arrays.toString(searchResponse.shardFailures()));
String[] executionTypes = new String[]{"uid", "bitset"};// either uid (faster, in general a bit more memory) or bitset (slower, but in general a bit less memory)
for (String executionType : executionTypes) {
System.out.println("--> Running has_child query with execution type " + executionType);
// run parent child constant query
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(
hasChildQuery("child", termQuery("tag", "tag1")).executionType(executionType)
)
.execute().actionGet();
if (searchResponse.failedShards() > 0) {
System.err.println("Search Failures " + Arrays.toString(searchResponse.shardFailures()));
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits [" + j + "], got [" + searchResponse.hits().totalHits() + "], expected [" + COUNT + "]");
}
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits [" + j + "], got [" + searchResponse.hits().totalHits() + "], expected [" + COUNT + "]");
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(
hasChildQuery("child", termQuery("tag", "tag1")).executionType(executionType)
)
.execute().actionGet();
if (searchResponse.failedShards() > 0) {
System.err.println("Search Failures " + Arrays.toString(searchResponse.shardFailures()));
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits [" + j + "], got [" + searchResponse.hits().totalHits() + "], expected [" + COUNT + "]");
}
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> has_child[" + executionType + "] Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
System.out.println("--> Running has_child[" + executionType + "] filter with match_all child query");
totalQueryTime = 0;
for (int j = 1; j <= QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(
hasChildQuery("child", matchAllQuery()).executionType(executionType)
)
.execute().actionGet();
if (searchResponse.failedShards() > 0) {
System.err.println("Search Failures " + Arrays.toString(searchResponse.shardFailures()));
}
long expected = (COUNT / BATCH) * BATCH;
if (searchResponse.hits().totalHits() != expected) {
System.err.println("--> mismatch on hits [" + j + "], got [" + searchResponse.hits().totalHits() + "], expected [" + expected + "]");
}
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> has_child[" + executionType + "] with match_all child query, Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
}
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch().setQuery(hasChildQuery("child", termQuery("tag", "tag1"))).execute().actionGet();
if (searchResponse.failedShards() > 0) {
System.err.println("Search Failures " + Arrays.toString(searchResponse.shardFailures()));
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits [" + j + "], got [" + searchResponse.hits().totalHits() + "], expected [" + COUNT + "]");
}
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> has_child Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
String[] executionTypes = new String[]{"uid", "indirect"}; // either uid (faster, in general a bit more memory) or indirect (slower, but in general a bit less memory)
for (String executionType : executionTypes) {
System.out.println("--> Running has_parent filter with " + executionType + " execution type");
// run parent child constant query
@ -196,7 +225,7 @@ public class ChildSearchBenchmark {
}
System.out.println("--> has_parent[" + executionType + "] Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
System.out.println("--> Running has_parent[" + executionType + "] filter with match_all query as parent query");
System.out.println("--> Running has_parent[" + executionType + "] filter with match_all parent query ");
totalQueryTime = 0;
for (int j = 1; j <= QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
@ -212,7 +241,7 @@ public class ChildSearchBenchmark {
}
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> has_parent[" + executionType + "] with match_all query as parent query Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
System.out.println("--> has_parent[" + executionType + "] with match_all parent query, Query Avg: " + (totalQueryTime / QUERY_COUNT) + "ms");
}
System.out.println("--> Running top_children query");
// run parent child score query

View File

@ -0,0 +1,32 @@
/*
* Licensed to ElasticSearch and Shay Banon 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.test.integration.search.child;
/**
* Runs super class tests, but with bitset execution type.
*/
public class BitsetExecutionChildQuerySearchTests extends SimpleChildQuerySearchTests {
@Override
protected String getExecutionMethod() {
return "bitset";
}
}

View File

@ -19,7 +19,6 @@
package org.elasticsearch.test.integration.search.child;
import com.beust.jcommander.internal.Maps;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.search.ShardSearchFailure;
@ -67,6 +66,10 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
return client("node1");
}
protected String getExecutionMethod() {
return "uid";
}
@Test
public void multiLevelChild() throws Exception {
client.admin().indices().prepareDelete().execute().actionGet();
@ -87,7 +90,15 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
client.admin().indices().prepareRefresh().execute().actionGet();
SearchResponse searchResponse = client.prepareSearch("test")
.setQuery(filteredQuery(matchAllQuery(), hasChildFilter("child", filteredQuery(termQuery("c_field", "c_value1"), hasChildFilter("grandchild", termQuery("gc_field", "gc_value1"))))))
.setQuery(
filteredQuery(
matchAllQuery(),
hasChildFilter(
"child",
filteredQuery(termQuery("c_field", "c_value1"), hasChildFilter("grandchild", termQuery("gc_field", "gc_value1")).executionType(getExecutionMethod()))
).executionType(getExecutionMethod())
)
)
.execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
@ -192,7 +203,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD QUERY
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod())).execute().actionGet();
if (searchResponse.failedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.shardFailures()) {
@ -203,13 +214,13 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -218,13 +229,13 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD FILTER
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")).executionType(getExecutionMethod()))).execute().actionGet();
if (searchResponse.failedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.shardFailures()) {
@ -235,7 +246,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -243,14 +254,14 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("p2"), equalTo("p1")));
// HAS PARENT FILTER
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", "p_value2")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", "p_value2")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("c3"));
assertThat(searchResponse.hits().getAt(1).id(), equalTo("c4"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", "p_value1")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", "p_value1")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -299,7 +310,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(parentToChildren.isEmpty(), equalTo(false));
for (Map.Entry<String, List<String>> parentToChildrenEntry : parentToChildren.entrySet()) {
SearchResponse searchResponse = client.prepareSearch("test")
.setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", parentToChildrenEntry.getKey()))))
.setQuery(constantScoreQuery(hasParentFilter("parent", termQuery("p_field", parentToChildrenEntry.getKey())).executionType(getExecutionMethod())))
.setSize(numChildDocsPerParent)
.execute().actionGet();
@ -368,19 +379,19 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD QUERY
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -389,19 +400,19 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD FILTER
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -463,19 +474,19 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD QUERY
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "blue")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red"))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "red")).executionType(getExecutionMethod())).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -484,19 +495,19 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
// HAS CHILD FILTER
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "blue")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p2"));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "red")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
@ -577,7 +588,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
assertThat(searchResponse.hits().getAt(0).sourceAsString(), containsString("\"p_value1\""));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
@ -596,7 +607,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
assertThat(searchResponse.hits().getAt(0).id(), equalTo("p1"));
assertThat(searchResponse.hits().getAt(0).sourceAsString(), containsString("\"p_value1_updated\""));
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")))).execute().actionGet();
searchResponse = client.prepareSearch("test").setQuery(constantScoreQuery(hasChildFilter("child", termQuery("c_field", "yellow")).executionType(getExecutionMethod()))).execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
assertThat(searchResponse.failedShards(), equalTo(0));
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
@ -625,7 +636,7 @@ public class SimpleChildQuerySearchTests extends AbstractNodesTests {
client.admin().indices().prepareRefresh().execute().actionGet();
SearchResponse searchResponse = client.prepareSearch("test").setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(boolQuery().mustNot(hasChildQuery("child", boolQuery().should(queryString("c_field:*")))))
.setQuery(boolQuery().mustNot(hasChildQuery("child", boolQuery().should(queryString("c_field:*"))).executionType(getExecutionMethod())))
.execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.shardFailures()), searchResponse.shardFailures().length, equalTo(0));
}