Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds ignore_unmapped option to nested and P/C queries #17748

Merged
merged 1 commit into from
Apr 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
* The default minimum number of children that are required to match for the parent to be considered a match.
*/
public static final int DEFAULT_MIN_CHILDREN = 0;

/**
* The default value for ignore_unmapped.
*/
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;
/*
* The default score mode that is used to combine score coming from multiple parent documents.
*/
Expand All @@ -74,6 +79,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
private static final ParseField MIN_CHILDREN_FIELD = new ParseField("min_children");
private static final ParseField SCORE_MODE_FIELD = new ParseField("score_mode");
private static final ParseField INNER_HITS_FIELD = new ParseField("inner_hits");
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");

private final QueryBuilder<?> query;

Expand All @@ -87,6 +93,8 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil

private InnerHitBuilder innerHitBuilder;

private boolean ignoreUnmapped = false;


public HasChildQueryBuilder(String type, QueryBuilder<?> query, int maxChildren, int minChildren, ScoreMode scoreMode,
InnerHitBuilder innerHitBuilder) {
Expand Down Expand Up @@ -123,6 +131,7 @@ public HasChildQueryBuilder(StreamInput in) throws IOException {
scoreMode = ScoreMode.values()[in.readVInt()];
query = in.readQuery();
innerHitBuilder = in.readOptionalWriteable(InnerHitBuilder::new);
ignoreUnmapped = in.readBoolean();
}

@Override
Expand All @@ -133,6 +142,7 @@ protected void doWriteTo(StreamOutput out) throws IOException {
out.writeVInt(scoreMode.ordinal());
out.writeQuery(query);
out.writeOptionalWriteable(innerHitBuilder);
out.writeBoolean(ignoreUnmapped);
}

/**
Expand Down Expand Up @@ -220,6 +230,25 @@ public int minChildren() {
*/
public int maxChildren() { return maxChildren; }

/**
* Sets whether the query builder should ignore unmapped types (and run a
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
* the type is unmapped.
*/
public HasChildQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
this.ignoreUnmapped = ignoreUnmapped;
return this;
}

/**
* Gets whether the query builder will ignore unmapped types (and run a
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
* the type is unmapped.
*/
public boolean ignoreUnmapped() {
return ignoreUnmapped;
}

@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
Expand All @@ -229,6 +258,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
builder.field(SCORE_MODE_FIELD.getPreferredName(), scoreModeAsString(scoreMode));
builder.field(MIN_CHILDREN_FIELD.getPreferredName(), minChildren);
builder.field(MAX_CHILDREN_FIELD.getPreferredName(), maxChildren);
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
printBoostAndQueryName(builder);
if (innerHitBuilder != null) {
builder.field(INNER_HITS_FIELD.getPreferredName(), innerHitBuilder, params);
Expand All @@ -243,6 +273,7 @@ public static HasChildQueryBuilder fromXContent(QueryParseContext parseContext)
ScoreMode scoreMode = HasChildQueryBuilder.DEFAULT_SCORE_MODE;
int minChildren = HasChildQueryBuilder.DEFAULT_MIN_CHILDREN;
int maxChildren = HasChildQueryBuilder.DEFAULT_MAX_CHILDREN;
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;
String queryName = null;
InnerHitBuilder innerHitBuilder = null;
String currentFieldName = null;
Expand Down Expand Up @@ -272,6 +303,8 @@ public static HasChildQueryBuilder fromXContent(QueryParseContext parseContext)
minChildren = parser.intValue(true);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_CHILDREN_FIELD)) {
maxChildren = parser.intValue(true);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
ignoreUnmapped = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
Expand All @@ -283,6 +316,7 @@ public static HasChildQueryBuilder fromXContent(QueryParseContext parseContext)
scoreMode, innerHitBuilder);
hasChildQueryBuilder.queryName(queryName);
hasChildQueryBuilder.boost(boost);
hasChildQueryBuilder.ignoreUnmapped(ignoreUnmapped);
return hasChildQueryBuilder;
}

Expand Down Expand Up @@ -331,7 +365,11 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
}
DocumentMapper childDocMapper = context.getMapperService().documentMapper(type);
if (childDocMapper == null) {
throw new QueryShardException(context, "[" + NAME + "] no mapping found for type [" + type + "]");
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
throw new QueryShardException(context, "[" + NAME + "] no mapping found for type [" + type + "]");
}
}
ParentFieldMapper parentFieldMapper = childDocMapper.parentFieldMapper();
if (parentFieldMapper.active() == false) {
Expand All @@ -344,8 +382,8 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
String parentType = parentFieldMapper.type();
DocumentMapper parentDocMapper = context.getMapperService().documentMapper(parentType);
if (parentDocMapper == null) {
throw new QueryShardException(context, "[" + NAME + "] Type [" + type + "] points to a non existent parent type ["
+ parentType + "]");
throw new QueryShardException(context,
"[" + NAME + "] Type [" + type + "] points to a non existent parent type [" + parentType + "]");
}

if (maxChildren > 0 && maxChildren < minChildren) {
Expand Down Expand Up @@ -464,12 +502,13 @@ protected boolean doEquals(HasChildQueryBuilder that) {
&& Objects.equals(scoreMode, that.scoreMode)
&& Objects.equals(minChildren, that.minChildren)
&& Objects.equals(maxChildren, that.maxChildren)
&& Objects.equals(innerHitBuilder, that.innerHitBuilder);
&& Objects.equals(innerHitBuilder, that.innerHitBuilder)
&& Objects.equals(ignoreUnmapped, that.ignoreUnmapped);
}

@Override
protected int doHashCode() {
return Objects.hash(query, type, scoreMode, minChildren, maxChildren, innerHitBuilder);
return Objects.hash(query, type, scoreMode, minChildren, maxChildren, innerHitBuilder, ignoreUnmapped);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.common.ParseField;
Expand Down Expand Up @@ -49,16 +50,23 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu

public static final boolean DEFAULT_SCORE = false;

/**
* The default value for ignore_unmapped.
*/
public static final boolean DEFAULT_IGNORE_UNMAPPED = false;

private static final ParseField QUERY_FIELD = new ParseField("query", "filter");
private static final ParseField SCORE_MODE_FIELD = new ParseField("score_mode").withAllDeprecated("score");
private static final ParseField TYPE_FIELD = new ParseField("parent_type", "type");
private static final ParseField SCORE_FIELD = new ParseField("score");
private static final ParseField INNER_HITS_FIELD = new ParseField("inner_hits");
private static final ParseField IGNORE_UNMAPPED_FIELD = new ParseField("ignore_unmapped");

private final QueryBuilder<?> query;
private final String type;
private boolean score = DEFAULT_SCORE;
private InnerHitBuilder innerHit;
private boolean ignoreUnmapped = false;

/**
* @param type The parent type
Expand Down Expand Up @@ -94,6 +102,7 @@ public HasParentQueryBuilder(StreamInput in) throws IOException {
score = in.readBoolean();
query = in.readQuery();
innerHit = in.readOptionalWriteable(InnerHitBuilder::new);
ignoreUnmapped = in.readBoolean();
}

@Override
Expand All @@ -102,6 +111,7 @@ protected void doWriteTo(StreamOutput out) throws IOException {
out.writeBoolean(score);
out.writeQuery(query);
out.writeOptionalWriteable(innerHit);
out.writeBoolean(ignoreUnmapped);
}

/**
Expand Down Expand Up @@ -150,6 +160,25 @@ public InnerHitBuilder innerHit() {
return innerHit;
}

/**
* Sets whether the query builder should ignore unmapped types (and run a
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
* the type is unmapped.
*/
public HasParentQueryBuilder ignoreUnmapped(boolean ignoreUnmapped) {
this.ignoreUnmapped = ignoreUnmapped;
return this;
}

/**
* Gets whether the query builder will ignore unmapped types (and run a
* {@link MatchNoDocsQuery} in place of this query) or throw an exception if
* the type is unmapped.
*/
public boolean ignoreUnmapped() {
return ignoreUnmapped;
}

@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
Query innerQuery;
Expand All @@ -166,8 +195,11 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
}
DocumentMapper parentDocMapper = context.getMapperService().documentMapper(type);
if (parentDocMapper == null) {
throw new QueryShardException(context, "[" + NAME + "] query configured 'parent_type' [" + type
+ "] is not a valid type");
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
throw new QueryShardException(context, "[" + NAME + "] query configured 'parent_type' [" + type + "] is not a valid type");
}
}

if (innerHit != null) {
Expand Down Expand Up @@ -220,6 +252,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
query.toXContent(builder, params);
builder.field(TYPE_FIELD.getPreferredName(), type);
builder.field(SCORE_FIELD.getPreferredName(), score);
builder.field(IGNORE_UNMAPPED_FIELD.getPreferredName(), ignoreUnmapped);
printBoostAndQueryName(builder);
if (innerHit != null) {
builder.field(INNER_HITS_FIELD.getPreferredName(), innerHit, params);
Expand All @@ -234,6 +267,7 @@ public static HasParentQueryBuilder fromXContent(QueryParseContext parseContext)
boolean score = HasParentQueryBuilder.DEFAULT_SCORE;
String queryName = null;
InnerHitBuilder innerHits = null;
boolean ignoreUnmapped = DEFAULT_IGNORE_UNMAPPED;

String currentFieldName = null;
XContentParser.Token token;
Expand Down Expand Up @@ -264,6 +298,8 @@ public static HasParentQueryBuilder fromXContent(QueryParseContext parseContext)
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, SCORE_FIELD)) {
score = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, IGNORE_UNMAPPED_FIELD)) {
ignoreUnmapped = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
Expand All @@ -273,7 +309,8 @@ public static HasParentQueryBuilder fromXContent(QueryParseContext parseContext)
}
}
}
return new HasParentQueryBuilder(parentType, iqb, score, innerHits).queryName(queryName).boost(boost);
return new HasParentQueryBuilder(parentType, iqb, score, innerHits).ignoreUnmapped(ignoreUnmapped).queryName(queryName)
.boost(boost);
}

@Override
Expand All @@ -286,12 +323,13 @@ protected boolean doEquals(HasParentQueryBuilder that) {
return Objects.equals(query, that.query)
&& Objects.equals(type, that.type)
&& Objects.equals(score, that.score)
&& Objects.equals(innerHit, that.innerHit);
&& Objects.equals(innerHit, that.innerHit)
&& Objects.equals(ignoreUnmapped, that.ignoreUnmapped);
}

@Override
protected int doHashCode() {
return Objects.hash(query, type, score, innerHit);
return Objects.hash(query, type, score, innerHit, ignoreUnmapped);
}

@Override
Expand Down
Loading