parent/child: several cleanups

* Dropped ScoreType in favour of Lucene's ScoreMode
* Removed `score_type` option from `has_child` and `has_parent` queries in favour for the already existing `score_mode` option.
* Removed the score mode `sum` in favour for the already existing `total` score mode. (`sum` doesn't exist in Lucene's ScoreMode class)
* If `max_children` is set to `0` it now really means that zero children are allowed to match.
This commit is contained in:
Martijn van Groningen 2015-09-10 16:16:48 +02:00
parent 60a2dd7020
commit ab0847e0df
12 changed files with 138 additions and 302 deletions

View File

@ -31,7 +31,7 @@ public class HasChildQueryBuilder extends QueryBuilder implements BoostableQuery
private float boost = 1.0f;
private String scoreType;
private String scoreMode;
private Integer minChildren;
@ -59,8 +59,8 @@ public class HasChildQueryBuilder extends QueryBuilder implements BoostableQuery
/**
* Defines how the scores from the matching child documents are mapped into the parent document.
*/
public HasChildQueryBuilder scoreType(String scoreType) {
this.scoreType = scoreType;
public HasChildQueryBuilder scoreMode(String scoreMode) {
this.scoreMode = scoreMode;
return this;
}
@ -105,8 +105,8 @@ public class HasChildQueryBuilder extends QueryBuilder implements BoostableQuery
if (boost != 1.0f) {
builder.field("boost", boost);
}
if (scoreType != null) {
builder.field("score_type", scoreType);
if (scoreMode != null) {
builder.field("score_mode", scoreMode);
}
if (minChildren != null) {
builder.field("min_children", minChildren);

View File

@ -38,7 +38,6 @@ import org.elasticsearch.index.query.support.InnerHitsQueryParserHelper;
import org.elasticsearch.index.query.support.XContentStructure;
import org.elasticsearch.search.fetch.innerhits.InnerHitsContext;
import org.elasticsearch.search.fetch.innerhits.InnerHitsSubSearchContext;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
@ -69,9 +68,9 @@ public class HasChildQueryParser implements QueryParser {
boolean queryFound = false;
float boost = 1.0f;
String childType = null;
ScoreType scoreType = ScoreType.NONE;
ScoreMode scoreMode = ScoreMode.None;
int minChildren = 0;
int maxChildren = 0;
int maxChildren = Integer.MAX_VALUE;
String queryName = null;
InnerHitsSubSearchContext innerHits = null;
@ -99,10 +98,8 @@ public class HasChildQueryParser implements QueryParser {
} else if (token.isValue()) {
if ("type".equals(currentFieldName) || "child_type".equals(currentFieldName) || "childType".equals(currentFieldName)) {
childType = parser.text();
} else if ("score_type".equals(currentFieldName) || "scoreType".equals(currentFieldName)) {
scoreType = ScoreType.fromString(parser.text());
} else if ("score_mode".equals(currentFieldName) || "scoreMode".equals(currentFieldName)) {
scoreType = ScoreType.fromString(parser.text());
scoreMode = parseScoreMode(parser.text());
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("min_children".equals(currentFieldName) || "minChildren".equals(currentFieldName)) {
@ -162,7 +159,7 @@ public class HasChildQueryParser implements QueryParser {
final Query query;
final ParentChildIndexFieldData parentChildIndexFieldData = parseContext.getForField(parentFieldMapper.fieldType());
query = joinUtilHelper(parentType, parentChildIndexFieldData, parentDocMapper.typeFilter(), scoreType, innerQuery, minChildren, maxChildren);
query = joinUtilHelper(parentType, parentChildIndexFieldData, parentDocMapper.typeFilter(), scoreMode, innerQuery, minChildren, maxChildren);
if (queryName != null) {
parseContext.addNamedQuery(queryName, query);
}
@ -170,35 +167,25 @@ public class HasChildQueryParser implements QueryParser {
return query;
}
public static Query joinUtilHelper(String parentType, ParentChildIndexFieldData parentChildIndexFieldData, Query toQuery, ScoreType scoreType, Query innerQuery, int minChildren, int maxChildren) throws IOException {
ScoreMode scoreMode;
// TODO: move entirely over from ScoreType to org.apache.lucene.join.ScoreMode, when we drop the 1.x parent child code.
switch (scoreType) {
case NONE:
scoreMode = ScoreMode.None;
break;
case MIN:
scoreMode = ScoreMode.Min;
break;
case MAX:
scoreMode = ScoreMode.Max;
break;
case SUM:
scoreMode = ScoreMode.Total;
break;
case AVG:
scoreMode = ScoreMode.Avg;
break;
default:
throw new UnsupportedOperationException("score type [" + scoreType + "] not supported");
}
// 0 in pre 2.x p/c impl means unbounded
if (maxChildren == 0) {
maxChildren = Integer.MAX_VALUE;
}
public static Query joinUtilHelper(String parentType, ParentChildIndexFieldData parentChildIndexFieldData, Query toQuery, ScoreMode scoreMode, Query innerQuery, int minChildren, int maxChildren) throws IOException {
return new LateParsingQuery(toQuery, innerQuery, minChildren, maxChildren, parentType, scoreMode, parentChildIndexFieldData);
}
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 ("total".equals(scoreModeString)) {
return ScoreMode.Total;
}
throw new IllegalArgumentException("No score mode for child query [" + scoreModeString + "] found");
}
final static class LateParsingQuery extends Query {
private final Query toQuery;

View File

@ -30,7 +30,7 @@ public class HasParentQueryBuilder extends QueryBuilder implements BoostableQuer
private final QueryBuilder queryBuilder;
private final String parentType;
private String scoreType;
private String scoreMode;
private float boost = 1.0f;
private String queryName;
private QueryInnerHitBuilder innerHit = null;
@ -53,8 +53,8 @@ public class HasParentQueryBuilder extends QueryBuilder implements BoostableQuer
/**
* Defines how the parent score is mapped into the child documents.
*/
public HasParentQueryBuilder scoreType(String scoreType) {
this.scoreType = scoreType;
public HasParentQueryBuilder scoreMode(String scoreMode) {
this.scoreMode = scoreMode;
return this;
}
@ -80,8 +80,8 @@ public class HasParentQueryBuilder extends QueryBuilder implements BoostableQuer
builder.field("query");
queryBuilder.toXContent(builder, params);
builder.field("parent_type", parentType);
if (scoreType != null) {
builder.field("score_type", scoreType);
if (scoreMode != null) {
builder.field("score_mode", scoreMode);
}
if (boost != 1.0f) {
builder.field("boost", boost);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query;
import org.apache.lucene.search.*;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
@ -88,13 +89,6 @@ public class HasParentQueryParser implements QueryParser {
} else if (token.isValue()) {
if ("type".equals(currentFieldName) || "parent_type".equals(currentFieldName) || "parentType".equals(currentFieldName)) {
parentType = parser.text();
} else if ("score_type".equals(currentFieldName) || "scoreType".equals(currentFieldName)) {
String scoreTypeValue = parser.text();
if ("score".equals(scoreTypeValue)) {
score = true;
} else if ("none".equals(scoreTypeValue)) {
score = false;
}
} else if ("score_mode".equals(currentFieldName) || "scoreMode".equals(currentFieldName)) {
String scoreModeValue = parser.text();
if ("score".equals(scoreModeValue)) {
@ -193,7 +187,7 @@ public class HasParentQueryParser implements QueryParser {
// wrap the query with type query
innerQuery = Queries.filtered(innerQuery, parentDocMapper.typeFilter());
Query childrenFilter = Queries.not(parentTypeQuery);
ScoreType scoreMode = score ? ScoreType.MAX : ScoreType.NONE;
ScoreMode scoreMode = score ? ScoreMode.Max : ScoreMode.None;
return joinUtilHelper(parentType, parentChildIndexFieldData, childrenFilter, scoreMode, innerQuery, 0, Integer.MAX_VALUE);
}

View File

@ -1,71 +0,0 @@
/*
* 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.index.query;
/**
* Defines how scores from child documents are mapped into the parent document.
*/
public enum ScoreType {
/**
* Only the lowest score of all matching child documents is mapped into the
* parent.
*/
MIN,
/**
* Only the highest score of all matching child documents is mapped into the
* parent.
*/
MAX,
/**
* The average score based on all matching child documents are mapped into
* the parent.
*/
AVG,
/**
* The matching children scores is summed up and mapped into the parent.
*/
SUM,
/**
* Scores are not taken into account
*/
NONE;
public static ScoreType fromString(String type) {
if ("none".equals(type)) {
return NONE;
} else if ("min".equals(type)) {
return MIN;
} else if ("max".equals(type)) {
return MAX;
} else if ("avg".equals(type)) {
return AVG;
} else if ("sum".equals(type)) {
return SUM;
} else if ("total".equals(type)) { // This name is consistent with: ScoreMode.Total
return SUM;
}
throw new IllegalArgumentException("No score type for child query [" + type + "] found");
}
}

View File

@ -281,12 +281,12 @@ public class ChildSearchBenchmark {
System.out.println("--> Running has_child query with score type");
// run parent child score query
for (int j = 0; j < QUERY_WARMUP; j++) {
client.prepareSearch(indexName).setQuery(hasChildQuery("child", termQuery("field2", parentChildIndexGenerator.getQueryValue())).scoreType("max")).execute().actionGet();
client.prepareSearch(indexName).setQuery(hasChildQuery("child", termQuery("field2", parentChildIndexGenerator.getQueryValue())).scoreMode("max")).execute().actionGet();
}
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasChildQuery("child", termQuery("field2", parentChildIndexGenerator.getQueryValue())).scoreType("max")).execute().actionGet();
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasChildQuery("child", termQuery("field2", parentChildIndexGenerator.getQueryValue())).scoreMode("max")).execute().actionGet();
if (j % 10 == 0) {
System.out.println("--> hits [" + j + "], got [" + searchResponse.getHits().totalHits() + "]");
}
@ -296,7 +296,7 @@ public class ChildSearchBenchmark {
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasChildQuery("child", matchAllQuery()).scoreType("max")).execute().actionGet();
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasChildQuery("child", matchAllQuery()).scoreMode("max")).execute().actionGet();
if (j % 10 == 0) {
System.out.println("--> hits [" + j + "], got [" + searchResponse.getHits().totalHits() + "]");
}
@ -307,12 +307,12 @@ public class ChildSearchBenchmark {
System.out.println("--> Running has_parent query with score type");
// run parent child score query
for (int j = 0; j < QUERY_WARMUP; j++) {
client.prepareSearch(indexName).setQuery(hasParentQuery("parent", termQuery("field1", parentChildIndexGenerator.getQueryValue())).scoreType("score")).execute().actionGet();
client.prepareSearch(indexName).setQuery(hasParentQuery("parent", termQuery("field1", parentChildIndexGenerator.getQueryValue())).scoreMode("score")).execute().actionGet();
}
totalQueryTime = 0;
for (int j = 1; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasParentQuery("parent", termQuery("field1", parentChildIndexGenerator.getQueryValue())).scoreType("score")).execute().actionGet();
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasParentQuery("parent", termQuery("field1", parentChildIndexGenerator.getQueryValue())).scoreMode("score")).execute().actionGet();
if (j % 10 == 0) {
System.out.println("--> hits [" + j + "], got [" + searchResponse.getHits().totalHits() + "]");
}
@ -322,7 +322,7 @@ public class ChildSearchBenchmark {
totalQueryTime = 0;
for (int j = 1; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasParentQuery("parent", matchAllQuery()).scoreType("score")).execute().actionGet();
SearchResponse searchResponse = client.prepareSearch(indexName).setQuery(hasParentQuery("parent", matchAllQuery()).scoreMode("score")).execute().actionGet();
if (j % 10 == 0) {
System.out.println("--> hits [" + j + "], got [" + searchResponse.getHits().totalHits() + "]");
}

View File

@ -178,7 +178,7 @@ public class ChildSearchShortCircuitBenchmark {
for (int i = 1; i < PARENT_COUNT; i *= 2) {
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch(indexName)
.setQuery(hasChildQuery("child", matchQuery("field2", i)).scoreType("max"))
.setQuery(hasChildQuery("child", matchQuery("field2", i)).scoreMode("max"))
.execute().actionGet();
if (searchResponse.getHits().totalHits() != i) {
System.err.println("--> mismatch on hits");

View File

@ -18,42 +18,38 @@
*/
package org.elasticsearch.index.query;
import org.elasticsearch.index.query.ScoreType;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.test.ESTestCase;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
/**
* Tests {@link ScoreType} to ensure backward compatibility of any changes.
*/
public class ScoreTypeTests extends ESTestCase {
public class HasChildQueryParserTests extends ESTestCase {
@Test
public void minFromString() {
assertThat("fromString(min) != MIN", ScoreType.MIN, equalTo(ScoreType.fromString("min")));
assertThat("fromString(min) != MIN", ScoreMode.Min, equalTo(HasChildQueryParser.parseScoreMode("min")));
}
@Test
public void maxFromString() {
assertThat("fromString(max) != MAX", ScoreType.MAX, equalTo(ScoreType.fromString("max")));
assertThat("fromString(max) != MAX", ScoreMode.Max, equalTo(HasChildQueryParser.parseScoreMode("max")));
}
@Test
public void avgFromString() {
assertThat("fromString(avg) != AVG", ScoreType.AVG, equalTo(ScoreType.fromString("avg")));
assertThat("fromString(avg) != AVG", ScoreMode.Avg, equalTo(HasChildQueryParser.parseScoreMode("avg")));
}
@Test
public void sumFromString() {
assertThat("fromString(sum) != SUM", ScoreType.SUM, equalTo(ScoreType.fromString("sum")));
// allowed for consistency with ScoreMode.Total:
assertThat("fromString(total) != SUM", ScoreType.SUM, equalTo(ScoreType.fromString("total")));
assertThat("fromString(total) != SUM", ScoreMode.Total, equalTo(HasChildQueryParser.parseScoreMode("total")));
}
@Test
public void noneFromString() {
assertThat("fromString(none) != NONE", ScoreType.NONE, equalTo(ScoreType.fromString("none")));
assertThat("fromString(none) != NONE", ScoreMode.None, equalTo(HasChildQueryParser.parseScoreMode("none")));
}
/**
@ -61,7 +57,7 @@ public class ScoreTypeTests extends ESTestCase {
*/
@Test(expected = IllegalArgumentException.class)
public void nullFromString_throwsException() {
ScoreType.fromString(null);
HasChildQueryParser.parseScoreMode(null);
}
/**
@ -69,6 +65,6 @@ public class ScoreTypeTests extends ESTestCase {
*/
@Test(expected = IllegalArgumentException.class)
public void unrecognizedFromString_throwsException() {
ScoreType.fromString("unrecognized value");
HasChildQueryParser.parseScoreMode("unrecognized value");
}
}

View File

@ -18,6 +18,7 @@
*/
package org.elasticsearch.search.child;
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.count.CountResponse;
@ -26,6 +27,7 @@ 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.common.collect.HppcMaps;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
@ -34,7 +36,6 @@ import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.query.HasChildQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.ScoreType;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.aggregations.AggregationBuilders;
@ -74,7 +75,6 @@ import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.scriptFunction;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.weightFactorFunction;
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
@ -293,11 +293,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
for (int i = 1; i <= 10; i++) {
logger.info("Round {}", i);
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(constantScoreQuery(hasChildQuery("child", matchAllQuery()).scoreType("max")))
.setQuery(constantScoreQuery(hasChildQuery("child", matchAllQuery()).scoreMode("max")))
.get();
assertNoFailures(searchResponse);
searchResponse = client().prepareSearch("test")
.setQuery(constantScoreQuery(hasParentQuery("parent", matchAllQuery()).scoreType("score")))
.setQuery(constantScoreQuery(hasParentQuery("parent", matchAllQuery()).scoreMode("score")))
.get();
assertNoFailures(searchResponse);
}
@ -555,11 +555,11 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().prepareIndex("test", "child", "c1").setSource("c_field", "1").setParent(parentId).get();
refresh();
CountResponse countResponse = client().prepareCount("test").setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreType("max"))
CountResponse countResponse = client().prepareCount("test").setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode("max"))
.get();
assertHitCount(countResponse, 1l);
countResponse = client().prepareCount("test").setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreType("score"))
countResponse = client().prepareCount("test").setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreMode("score"))
.get();
assertHitCount(countResponse, 1l);
@ -586,20 +586,20 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse searchResponse = client().prepareSearch("test")
.setExplain(true)
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreType("max"))
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode("max"))
.get();
assertHitCount(searchResponse, 1l);
assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), equalTo("Score based on join value p1"));
searchResponse = client().prepareSearch("test")
.setExplain(true)
.setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreType("score"))
.setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreMode("score"))
.get();
assertHitCount(searchResponse, 1l);
assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), equalTo("Score based on join value p1"));
ExplainResponse explainResponse = client().prepareExplain("test", "parent", parentId)
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreType("max"))
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode("max"))
.get();
assertThat(explainResponse.isExists(), equalTo(true));
assertThat(explainResponse.getExplanation().getDetails()[0].getDescription(), equalTo("Score based on join value p1"));
@ -677,7 +677,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
"child",
QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
scriptFunction(new Script("doc['c_field1'].value")))
.boostMode(CombineFunction.REPLACE.getName())).scoreType("sum")).get();
.boostMode(CombineFunction.REPLACE.getName())).scoreMode("total")).get();
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("1"));
@ -694,7 +694,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
"child",
QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
scriptFunction(new Script("doc['c_field1'].value")))
.boostMode(CombineFunction.REPLACE.getName())).scoreType("max")).get();
.boostMode(CombineFunction.REPLACE.getName())).scoreMode("max")).get();
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
@ -711,7 +711,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
"child",
QueryBuilders.functionScoreQuery(matchQuery("c_field2", 0),
scriptFunction(new Script("doc['c_field1'].value")))
.boostMode(CombineFunction.REPLACE.getName())).scoreType("avg")).get();
.boostMode(CombineFunction.REPLACE.getName())).scoreMode("avg")).get();
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
@ -728,7 +728,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
"parent",
QueryBuilders.functionScoreQuery(matchQuery("p_field1", "p_value3"),
scriptFunction(new Script("doc['p_field2'].value")))
.boostMode(CombineFunction.REPLACE.getName())).scoreType("score"))
.boostMode(CombineFunction.REPLACE.getName())).scoreMode("score"))
.addSort(SortBuilders.fieldSort("c_field3")).addSort(SortBuilders.scoreSort()).get();
assertThat(response.getHits().totalHits(), equalTo(7l));
@ -768,7 +768,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertNoFailures(response);
assertThat(response.getHits().totalHits(), equalTo(0l));
response = client().prepareSearch("test").setQuery(QueryBuilders.hasChildQuery("child", matchQuery("text", "value")).scoreType("max"))
response = client().prepareSearch("test").setQuery(QueryBuilders.hasChildQuery("child", matchQuery("text", "value")).scoreMode("max"))
.get();
assertNoFailures(response);
assertThat(response.getHits().totalHits(), equalTo(0l));
@ -777,7 +777,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertNoFailures(response);
assertThat(response.getHits().totalHits(), equalTo(0l));
response = client().prepareSearch("test").setQuery(QueryBuilders.hasParentQuery("child", matchQuery("text", "value")).scoreType("score"))
response = client().prepareSearch("test").setQuery(QueryBuilders.hasParentQuery("child", matchQuery("text", "value")).scoreMode("score"))
.get();
assertNoFailures(response);
assertThat(response.getHits().totalHits(), equalTo(0l));
@ -864,7 +864,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchType[] searchTypes = new SearchType[]{SearchType.QUERY_THEN_FETCH, SearchType.DFS_QUERY_THEN_FETCH};
for (SearchType searchType : searchTypes) {
SearchResponse searchResponse = client().prepareSearch("test").setSearchType(searchType)
.setQuery(hasChildQuery("child", prefixQuery("c_field", "c")).scoreType("max")).addSort("p_field", SortOrder.ASC)
.setQuery(hasChildQuery("child", prefixQuery("c_field", "c")).scoreMode("max")).addSort("p_field", SortOrder.ASC)
.setSize(5).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(10L));
@ -875,7 +875,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(searchResponse.getHits().hits()[4].id(), equalTo("p004"));
searchResponse = client().prepareSearch("test").setSearchType(searchType)
.setQuery(hasParentQuery("parent", prefixQuery("p_field", "p")).scoreType("score")).addSort("c_field", SortOrder.ASC)
.setQuery(hasParentQuery("parent", prefixQuery("p_field", "p")).scoreMode("score")).addSort("c_field", SortOrder.ASC)
.setSize(5).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(500L));
@ -907,7 +907,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
refresh();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).scoreType("sum")).get();
.setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).scoreMode("total")).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
assertThat(searchResponse.getHits().getAt(0).id(), equalTo("p1"));
@ -917,7 +917,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.prepareSearch("test")
.setQuery(
boolQuery().must(matchQuery("c_field", "x")).must(
hasParentQuery("parent", termQuery("p_field", "p_value2")).scoreType("score"))).get();
hasParentQuery("parent", termQuery("p_field", "p_value2")).scoreMode("score"))).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
assertThat(searchResponse.getHits().getAt(0).id(), equalTo("c3"));
@ -932,7 +932,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().admin().indices().prepareRefresh("test").get();
}
searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).scoreType("sum"))
searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", termQuery("c_field", "yellow")).scoreMode("total"))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
@ -943,7 +943,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
.prepareSearch("test")
.setQuery(
boolQuery().must(matchQuery("c_field", "x")).must(
hasParentQuery("parent", termQuery("p_field", "p_value2")).scoreType("score"))).get();
hasParentQuery("parent", termQuery("p_field", "p_value2")).scoreMode("score"))).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
assertThat(searchResponse.getHits().getAt(0).id(), Matchers.anyOf(equalTo("c3"), equalTo("c4")));
@ -968,7 +968,7 @@ 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()).scoreType("sum"))
SearchResponse searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", matchAllQuery()).scoreMode("total"))
.setMinScore(3) // Score needs to be 3 or above!
.get();
assertNoFailures(searchResponse);
@ -1237,15 +1237,15 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
client().prepareIndex("test", "child", "c3").setParent("p2").setSource("c_field", "red").get();
refresh();
String scoreMode = ScoreType.values()[getRandom().nextInt(ScoreType.values().length)].name().toLowerCase(Locale.ROOT);
String scoreMode = ScoreMode.values()[getRandom().nextInt(ScoreMode.values().length)].name().toLowerCase(Locale.ROOT);
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "blue")).scoreType(scoreMode)).filter(notQuery(termQuery("p_field", "3"))))
.setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "blue")).scoreMode(scoreMode)).filter(notQuery(termQuery("p_field", "3"))))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch("test")
.setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "red")).scoreType(scoreMode)).filter(notQuery(termQuery("p_field", "3"))))
.setQuery(boolQuery().must(QueryBuilders.hasChildQuery("child", termQuery("c_field", "red")).scoreMode(scoreMode)).filter(notQuery(termQuery("p_field", "3"))))
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
@ -1263,13 +1263,13 @@ 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")).scoreType("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")).scoreType("score").queryName("test"))
searchResponse = client().prepareSearch("test").setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreMode("score").queryName("test"))
.get();
assertHitCount(searchResponse, 1l);
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(1));
@ -1311,7 +1311,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
try {
client().prepareSearch("test")
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreType("max"))
.setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode("max"))
.get();
fail();
} catch (SearchPhaseExecutionException e) {
@ -1329,7 +1329,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
try {
client().prepareSearch("test")
.setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreType("score"))
.setQuery(hasParentQuery("parent", termQuery("p_field", "1")).scoreMode("score"))
.get();
fail();
} catch (SearchPhaseExecutionException e) {
@ -1579,28 +1579,23 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
return indexBuilders;
}
private SearchResponse minMaxQuery(String scoreType, int minChildren, int maxChildren) throws SearchPhaseExecutionException {
return client()
.prepareSearch("test")
.setQuery(
QueryBuilders
.hasChildQuery(
private SearchResponse minMaxQuery(String scoreMode, int minChildren, Integer maxChildren) throws SearchPhaseExecutionException {
HasChildQueryBuilder hasChildQuery = hasChildQuery(
"child",
QueryBuilders.functionScoreQuery(constantScoreQuery(QueryBuilders.termQuery("foo", "two"))).boostMode("replace").scoreMode("sum")
.add(QueryBuilders.matchAllQuery(), weightFactorFunction(1))
.add(QueryBuilders.termQuery("foo", "three"), weightFactorFunction(1))
.add(QueryBuilders.termQuery("foo", "four"), weightFactorFunction(1))).scoreType(scoreType)
.minChildren(minChildren).maxChildren(maxChildren))
.addSort("_score", SortOrder.DESC).addSort("id", SortOrder.ASC).get();
.add(QueryBuilders.termQuery("foo", "four"), weightFactorFunction(1))).scoreMode(scoreMode)
.minChildren(minChildren);
if (maxChildren != null) {
hasChildQuery.maxChildren(maxChildren);
}
private SearchResponse minMaxFilter(int minChildren, int maxChildren) throws SearchPhaseExecutionException {
return client()
.prepareSearch("test")
.setQuery(
QueryBuilders.constantScoreQuery(QueryBuilders.hasChildQuery("child", termQuery("foo", "two"))
.minChildren(minChildren).maxChildren(maxChildren)))
.addSort("id", SortOrder.ASC).setTrackScores(true).get();
.setQuery(hasChildQuery)
.addSort("_score", SortOrder.DESC).addSort("id", SortOrder.ASC).get();
}
@Test
@ -1614,7 +1609,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
SearchResponse response;
// Score mode = NONE
response = minMaxQuery("none", 0, 0);
response = minMaxQuery("none", 0, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
@ -1624,7 +1619,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("none", 1, 0);
response = minMaxQuery("none", 1, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
@ -1634,7 +1629,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("none", 2, 0);
response = minMaxQuery("none", 2, null);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
@ -1642,13 +1637,13 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[1].id(), equalTo("4"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
response = minMaxQuery("none", 3, 0);
response = minMaxQuery("none", 3, null);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
response = minMaxQuery("none", 4, 0);
response = minMaxQuery("none", 4, null);
assertThat(response.getHits().totalHits(), equalTo(0l));
@ -1693,8 +1688,8 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(e.toString(), containsString("[has_child] 'max_children' is less than 'min_children'"));
}
// Score mode = SUM
response = minMaxQuery("sum", 0, 0);
// Score mode = TOTAL
response = minMaxQuery("total", 0, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1704,7 +1699,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("sum", 1, 0);
response = minMaxQuery("total", 1, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1714,7 +1709,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("sum", 2, 0);
response = minMaxQuery("total", 2, null);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1722,17 +1717,17 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(3f));
response = minMaxQuery("sum", 3, 0);
response = minMaxQuery("total", 3, null);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
assertThat(response.getHits().hits()[0].score(), equalTo(6f));
response = minMaxQuery("sum", 4, 0);
response = minMaxQuery("total", 4, null);
assertThat(response.getHits().totalHits(), equalTo(0l));
response = minMaxQuery("sum", 0, 4);
response = minMaxQuery("total", 0, 4);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1742,7 +1737,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("sum", 0, 3);
response = minMaxQuery("total", 0, 3);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1752,7 +1747,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("sum", 0, 2);
response = minMaxQuery("total", 0, 2);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
@ -1760,21 +1755,21 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[1].id(), equalTo("2"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
response = minMaxQuery("sum", 2, 2);
response = minMaxQuery("total", 2, 2);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
assertThat(response.getHits().hits()[0].score(), equalTo(3f));
try {
response = minMaxQuery("sum", 3, 2);
response = minMaxQuery("total", 3, 2);
fail();
} catch (SearchPhaseExecutionException e) {
assertThat(e.toString(), containsString("[has_child] 'max_children' is less than 'min_children'"));
}
// Score mode = MAX
response = minMaxQuery("max", 0, 0);
response = minMaxQuery("max", 0, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1784,7 +1779,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("max", 1, 0);
response = minMaxQuery("max", 1, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1794,7 +1789,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("max", 2, 0);
response = minMaxQuery("max", 2, null);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1802,13 +1797,13 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(2f));
response = minMaxQuery("max", 3, 0);
response = minMaxQuery("max", 3, null);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
assertThat(response.getHits().hits()[0].score(), equalTo(3f));
response = minMaxQuery("max", 4, 0);
response = minMaxQuery("max", 4, null);
assertThat(response.getHits().totalHits(), equalTo(0l));
@ -1854,7 +1849,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
}
// Score mode = AVG
response = minMaxQuery("avg", 0, 0);
response = minMaxQuery("avg", 0, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1864,7 +1859,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("avg", 1, 0);
response = minMaxQuery("avg", 1, null);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1874,7 +1869,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[2].id(), equalTo("2"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxQuery("avg", 2, 0);
response = minMaxQuery("avg", 2, null);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
@ -1882,13 +1877,13 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1.5f));
response = minMaxQuery("avg", 3, 0);
response = minMaxQuery("avg", 3, null);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
assertThat(response.getHits().hits()[0].score(), equalTo(2f));
response = minMaxQuery("avg", 4, 0);
response = minMaxQuery("avg", 4, null);
assertThat(response.getHits().totalHits(), equalTo(0l));
@ -1932,87 +1927,6 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
} catch (SearchPhaseExecutionException e) {
assertThat(e.toString(), containsString("[has_child] 'max_children' is less than 'min_children'"));
}
// HasChildFilter
response = minMaxFilter(0, 0);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxFilter(1, 0);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxFilter(2, 0);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("4"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
response = minMaxFilter(3, 0);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("4"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
response = minMaxFilter(4, 0);
assertThat(response.getHits().totalHits(), equalTo(0l));
response = minMaxFilter(0, 4);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxFilter(0, 3);
assertThat(response.getHits().totalHits(), equalTo(3l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
assertThat(response.getHits().hits()[2].id(), equalTo("4"));
assertThat(response.getHits().hits()[2].score(), equalTo(1f));
response = minMaxFilter(0, 2);
assertThat(response.getHits().totalHits(), equalTo(2l));
assertThat(response.getHits().hits()[0].id(), equalTo("2"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
assertThat(response.getHits().hits()[1].id(), equalTo("3"));
assertThat(response.getHits().hits()[1].score(), equalTo(1f));
response = minMaxFilter(2, 2);
assertThat(response.getHits().totalHits(), equalTo(1l));
assertThat(response.getHits().hits()[0].id(), equalTo("3"));
assertThat(response.getHits().hits()[0].score(), equalTo(1f));
try {
response = minMaxFilter(3, 2);
fail();
} catch (SearchPhaseExecutionException e) {
assertThat(e.toString(), containsString("[has_child] 'max_children' is less than 'min_children'"));
}
}
@Test

View File

@ -72,3 +72,19 @@ The format of the join between parent and child documents have changed with the
format can't read from version `3.0.0` and onwards. The new format allows for a much more efficient and
scalable join between parent and child documents and the join data structures are stored on on disk
data structures as opposed as before the join data structures were stored in the jvm heap space.
==== `score_type` has been removed
The `score_type` option has been removed from the `has_child` and `has_parent` queries in favour of the `score_mode` option
which does the exact same thing.
==== `sum` score mode removed
The `sum` score mode has been removed in favour of the `total` mode which doesn the same and is already available in
previous versions.
==== `max_children` option
When `max_children` was set to `0` on the `has_child` query then there was no upper limit on how many children documents
are allowed to match. This has changed and `0` now really means to zero child documents are allowed. If no upper limit
is needed then the `max_children` option shouldn't be defined at all on the `has_child` query.

View File

@ -23,9 +23,9 @@ an example:
==== Scoring capabilities
The `has_child` also has scoring support. The
supported score types are `min`, `max`, `sum`, `avg` or `none`. The default is
supported score modes are `min`, `max`, `total`, `avg` or `none`. The default is
`none` and yields the same behaviour as in previous versions. If the
score type is set to another value than `none`, the scores of all the
score mode is set to another value than `none`, the scores of all the
matching child documents are aggregated into the associated parent
documents. The score type can be specified with the `score_mode` field
inside the `has_child` query:

View File

@ -30,7 +30,7 @@ this ignores the score from the parent document. The score is in this
case equal to the boost on the `has_parent` query (Defaults to 1). If
the score type is set to `score`, then the score of the matching parent
document is aggregated into the child documents belonging to the
matching parent document. The score type can be specified with the
matching parent document. The score mode can be specified with the
`score_mode` field inside the `has_parent` query:
[source,js]