From 2a71a7bffc7ad1262cdf84554277653858c3b7f5 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Fri, 2 Jun 2017 14:34:20 +0200 Subject: Change `has_child`, `has_parent` queries and `childen` aggregation to work with the new join field type and at the same time maintaining support for the `_parent` meta field type. Relates to #20257 --- .../aggregations/ChildrenAggregationBuilder.java | 29 ++++++++++-- .../join/mapper/MetaJoinFieldMapper.java | 11 +++-- .../join/mapper/ParentIdFieldMapper.java | 25 ++++++++++- .../join/mapper/ParentJoinFieldMapper.java | 7 +-- .../join/query/HasChildQueryBuilder.java | 51 +++++++++++++++++----- .../join/query/HasParentQueryBuilder.java | 33 +++++++++++++- 6 files changed, 133 insertions(+), 23 deletions(-) (limited to 'modules/parent-join/src/main/java/org') diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java index 35dc4eacbf..3560736e44 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java @@ -30,6 +30,8 @@ import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.ParentFieldMapper; import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.join.mapper.ParentIdFieldMapper; +import org.elasticsearch.join.mapper.ParentJoinFieldMapper; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.support.FieldContext; @@ -92,8 +94,30 @@ public class ChildrenAggregationBuilder @Override protected ValuesSourceConfig resolveConfig(SearchContext context) { ValuesSourceConfig config = new ValuesSourceConfig<>(ValuesSourceType.BYTES); - DocumentMapper childDocMapper = context.mapperService().documentMapper(childType); + if (context.mapperService().getIndexSettings().isSingleType()) { + joinFieldResolveConfig(context, config); + } else { + parentFieldResolveConfig(context, config); + } + return config; + } + + private void joinFieldResolveConfig(SearchContext context, ValuesSourceConfig config) { + ParentJoinFieldMapper parentJoinFieldMapper = ParentJoinFieldMapper.getMapper(context.mapperService()); + ParentIdFieldMapper parentIdFieldMapper = parentJoinFieldMapper.getParentIdFieldMapper(childType, false); + if (parentIdFieldMapper != null) { + parentFilter = parentIdFieldMapper.getParentFilter(); + childFilter = parentIdFieldMapper.getChildFilter(childType); + MappedFieldType fieldType = parentIdFieldMapper.fieldType(); + final SortedSetDVOrdinalsIndexFieldData fieldData = context.fieldData().getForField(fieldType); + config.fieldContext(new FieldContext(fieldType.name(), fieldData, fieldType)); + } else { + config.unmapped(true); + } + } + private void parentFieldResolveConfig(SearchContext context, ValuesSourceConfig config) { + DocumentMapper childDocMapper = context.mapperService().documentMapper(childType); if (childDocMapper != null) { ParentFieldMapper parentFieldMapper = childDocMapper.parentFieldMapper(); if (!parentFieldMapper.active()) { @@ -107,14 +131,13 @@ public class ChildrenAggregationBuilder MappedFieldType parentFieldType = parentDocMapper.parentFieldMapper().getParentJoinFieldType(); final SortedSetDVOrdinalsIndexFieldData fieldData = context.fieldData().getForField(parentFieldType); config.fieldContext(new FieldContext(parentFieldType.name(), fieldData, - parentFieldType)); + parentFieldType)); } else { config.unmapped(true); } } else { config.unmapped(true); } - return config; } @Override diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java index 43608e9b54..db9fae9b47 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java @@ -40,7 +40,7 @@ import java.util.List; * This class is also used to quickly retrieve the parent-join field defined in a mapping without * specifying the name of the field. */ -class MetaJoinFieldMapper extends FieldMapper { +public class MetaJoinFieldMapper extends FieldMapper { static final String NAME = "_parent_join"; static final String CONTENT_TYPE = "parent_join"; @@ -68,8 +68,9 @@ class MetaJoinFieldMapper extends FieldMapper { } } - static final class MetaJoinFieldType extends StringFieldType { - ParentJoinFieldMapper mapper; + public static class MetaJoinFieldType extends StringFieldType { + + private ParentJoinFieldMapper mapper; MetaJoinFieldType() {} @@ -100,6 +101,10 @@ class MetaJoinFieldMapper extends FieldMapper { BytesRef binaryValue = (BytesRef) value; return binaryValue.utf8ToString(); } + + public ParentJoinFieldMapper getMapper() { + return mapper; + } } MetaJoinFieldMapper(String name, MappedFieldType fieldType, Settings indexSettings) { diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java index 7a042eae84..cc2815c373 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java @@ -23,6 +23,12 @@ import org.apache.lucene.document.Field; import org.apache.lucene.document.SortedDocValuesField; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Settings; @@ -47,7 +53,7 @@ public final class ParentIdFieldMapper extends FieldMapper { static final String CONTENT_TYPE = "parent"; static class Defaults { - public static final MappedFieldType FIELD_TYPE = new ParentIdFieldType(); + static final MappedFieldType FIELD_TYPE = new ParentIdFieldType(); static { FIELD_TYPE.setTokenized(false); @@ -86,7 +92,7 @@ public final class ParentIdFieldMapper extends FieldMapper { } public static final class ParentIdFieldType extends StringFieldType { - public ParentIdFieldType() { + ParentIdFieldType() { setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } @@ -145,6 +151,9 @@ public final class ParentIdFieldMapper extends FieldMapper { return parentName; } + public Query getParentFilter() { + return new TermQuery(new Term(name().substring(0, name().indexOf('#')), parentName)); + } /** * Returns the children names associated with this mapper. */ @@ -152,6 +161,18 @@ public final class ParentIdFieldMapper extends FieldMapper { return children; } + public Query getChildFilter(String type) { + return new TermQuery(new Term(name().substring(0, name().indexOf('#')), type)); + } + + public Query getChildrenFilter() { + BooleanQuery.Builder builder = new BooleanQuery.Builder(); + for (String child : children) { + builder.add(getChildFilter(child), BooleanClause.Occur.SHOULD); + } + return new ConstantScoreQuery(builder.build()); + } + @Override protected void parseCreateField(ParseContext context, List fields) throws IOException { if (context.externalValueSet() == false) { diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java index d9c12d85c1..ecabbb096e 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java @@ -81,7 +81,7 @@ public final class ParentJoinFieldMapper extends FieldMapper { public static ParentJoinFieldMapper getMapper(MapperService service) { MetaJoinFieldMapper.MetaJoinFieldType fieldType = (MetaJoinFieldMapper.MetaJoinFieldType) service.fullName(MetaJoinFieldMapper.NAME); - return fieldType == null ? null : fieldType.mapper; + return fieldType == null ? null : fieldType.getMapper(); } private static String getParentIdFieldName(String joinFieldName, String parentName) { @@ -121,11 +121,11 @@ public final class ParentJoinFieldMapper extends FieldMapper { } } - static class Builder extends FieldMapper.Builder { + public static class Builder extends FieldMapper.Builder { final List parentIdFieldBuilders = new ArrayList<>(); boolean eagerGlobalOrdinals = true; - Builder(String name) { + public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE); builder = this; } @@ -431,4 +431,5 @@ public final class ParentJoinFieldMapper extends FieldMapper { } } } + } diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java index f574236b35..6485b8f649 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java @@ -49,6 +49,8 @@ import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryRewriteContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardException; +import org.elasticsearch.join.mapper.ParentIdFieldMapper; +import org.elasticsearch.join.mapper.ParentJoinFieldMapper; import java.io.IOException; import java.util.HashMap; @@ -305,6 +307,34 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder