summaryrefslogtreecommitdiff
path: root/modules/parent-join/src/main/java/org
diff options
context:
space:
mode:
authorMartijn van Groningen <martijn.v.groningen@gmail.com>2017-06-02 14:34:20 +0200
committerMartijn van Groningen <martijn.v.groningen@gmail.com>2017-06-02 23:27:16 +0200
commit2a71a7bffc7ad1262cdf84554277653858c3b7f5 (patch)
tree8f10bfd683b66699a0a91aa1f7e869436d4eceb9 /modules/parent-join/src/main/java/org
parenta32d1b91fa44c005ea41fa17323ea6bc65352092 (diff)
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
Diffstat (limited to 'modules/parent-join/src/main/java/org')
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java29
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java11
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java25
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java7
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/query/HasChildQueryBuilder.java51
-rw-r--r--modules/parent-join/src/main/java/org/elasticsearch/join/query/HasParentQueryBuilder.java33
6 files changed, 133 insertions, 23 deletions
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<WithOrdinals> resolveConfig(SearchContext context) {
ValuesSourceConfig<WithOrdinals> 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<WithOrdinals> 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<WithOrdinals> 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<IndexableField> 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<Builder, ParentJoinFieldMapper> {
+ public static class Builder extends FieldMapper.Builder<Builder, ParentJoinFieldMapper> {
final List<ParentIdFieldMapper.Builder> 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<HasChildQueryBuil
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
+ if (context.getIndexSettings().isSingleType()) {
+ return joinFieldDoToQuery(context);
+ } else {
+ return parentFieldDoToQuery(context);
+ }
+ }
+
+ private Query joinFieldDoToQuery(QueryShardContext context) throws IOException {
+ ParentJoinFieldMapper joinFieldMapper = ParentJoinFieldMapper.getMapper(context.getMapperService());
+ ParentIdFieldMapper parentIdFieldMapper = joinFieldMapper.getParentIdFieldMapper(type, false);
+ if (parentIdFieldMapper != null) {
+ Query parentFilter = parentIdFieldMapper.getParentFilter();
+ Query childFilter = parentIdFieldMapper.getChildFilter(type);
+ Query innerQuery = Queries.filtered(query.toQuery(context), childFilter);
+ MappedFieldType fieldType = parentIdFieldMapper.fieldType();
+ final SortedSetDVOrdinalsIndexFieldData fieldData = context.getForField(fieldType);
+ return new LateParsingQuery(parentFilter, innerQuery, minChildren(), maxChildren(),
+ fieldType.name(), scoreMode, fieldData, context.getSearchSimilarity());
+ } else {
+ if (ignoreUnmapped) {
+ return new MatchNoDocsQuery();
+ } else {
+ throw new QueryShardException(context, "[" + NAME + "] join field has no parent type configured");
+ }
+ }
+ }
+
+ private Query parentFieldDoToQuery(QueryShardContext context) throws IOException {
Query innerQuery;
final String[] previousTypes = context.getTypes();
context.setTypes(type);
@@ -313,8 +343,7 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
} finally {
context.setTypes(previousTypes);
}
-
- DocumentMapper childDocMapper = context.documentMapper(type);
+ DocumentMapper childDocMapper = context.getMapperService().documentMapper(type);
if (childDocMapper == null) {
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
@@ -330,16 +359,17 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
DocumentMapper parentDocMapper = context.getMapperService().documentMapper(parentType);
if (parentDocMapper == null) {
throw new QueryShardException(context,
- "[" + NAME + "] Type [" + type + "] points to a non existent parent type [" + parentType + "]");
+ "[" + NAME + "] Type [" + type + "] points to a non existent parent type [" + parentType + "]");
}
// wrap the query with type query
innerQuery = Queries.filtered(innerQuery, childDocMapper.typeFilter(context));
+ String joinField = ParentFieldMapper.joinField(parentType);
final MappedFieldType parentFieldType = parentDocMapper.parentFieldMapper().getParentJoinFieldType();
final SortedSetDVOrdinalsIndexFieldData fieldData = context.getForField(parentFieldType);
return new LateParsingQuery(parentDocMapper.typeFilter(context), innerQuery, minChildren(), maxChildren(),
- parentType, scoreMode, fieldData, context.getSearchSimilarity());
+ joinField, scoreMode, fieldData, context.getSearchSimilarity());
}
/**
@@ -358,19 +388,19 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
private final Query innerQuery;
private final int minChildren;
private final int maxChildren;
- private final String parentType;
+ private final String joinField;
private final ScoreMode scoreMode;
private final SortedSetDVOrdinalsIndexFieldData fieldDataJoin;
private final Similarity similarity;
LateParsingQuery(Query toQuery, Query innerQuery, int minChildren, int maxChildren,
- String parentType, ScoreMode scoreMode,
+ String joinField, ScoreMode scoreMode,
SortedSetDVOrdinalsIndexFieldData fieldData, Similarity similarity) {
this.toQuery = toQuery;
this.innerQuery = innerQuery;
this.minChildren = minChildren;
this.maxChildren = maxChildren;
- this.parentType = parentType;
+ this.joinField = joinField;
this.scoreMode = scoreMode;
this.fieldDataJoin = fieldData;
this.similarity = similarity;
@@ -383,7 +413,6 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
return rewritten;
}
if (reader instanceof DirectoryReader) {
- String joinField = ParentFieldMapper.joinField(parentType);
IndexSearcher indexSearcher = new IndexSearcher(reader);
indexSearcher.setQueryCache(null);
indexSearcher.setSimilarity(similarity);
@@ -414,18 +443,18 @@ public class HasChildQueryBuilder extends AbstractQueryBuilder<HasChildQueryBuil
if (maxChildren != that.maxChildren) return false;
if (!toQuery.equals(that.toQuery)) return false;
if (!innerQuery.equals(that.innerQuery)) return false;
- if (!parentType.equals(that.parentType)) return false;
+ if (!joinField.equals(that.joinField)) return false;
return scoreMode == that.scoreMode;
}
@Override
public int hashCode() {
- return Objects.hash(classHash(), toQuery, innerQuery, minChildren, maxChildren, parentType, scoreMode);
+ return Objects.hash(getClass(), toQuery, innerQuery, minChildren, maxChildren, joinField, scoreMode);
}
@Override
public String toString(String s) {
- return "LateParsingQuery {parentType=" + parentType + "}";
+ return "LateParsingQuery {joinField=" + joinField + "}";
}
public int getMinChildren() {
diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasParentQueryBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasParentQueryBuilder.java
index 7bcbf7c611..3d23fac01b 100644
--- a/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasParentQueryBuilder.java
+++ b/modules/parent-join/src/main/java/org/elasticsearch/join/query/HasParentQueryBuilder.java
@@ -55,6 +55,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 org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.fetch.subphase.InnerHitsContext;
@@ -187,6 +189,35 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
+ if (context.getIndexSettings().isSingleType()) {
+ return joinFieldDoToQuery(context);
+ } else {
+ return parentFieldDoToQuery(context);
+ }
+ }
+
+ private Query joinFieldDoToQuery(QueryShardContext context) throws IOException {
+ ParentJoinFieldMapper joinFieldMapper = ParentJoinFieldMapper.getMapper(context.getMapperService());
+ ParentIdFieldMapper parentIdFieldMapper = joinFieldMapper.getParentIdFieldMapper(type, true);
+ if (parentIdFieldMapper != null) {
+ Query parentFilter = parentIdFieldMapper.getParentFilter();
+ Query innerQuery = Queries.filtered(query.toQuery(context), parentFilter);
+ Query childFilter = parentIdFieldMapper.getChildrenFilter();
+ MappedFieldType fieldType = parentIdFieldMapper.fieldType();
+ final SortedSetDVOrdinalsIndexFieldData fieldData = context.getForField(fieldType);
+ return new HasChildQueryBuilder.LateParsingQuery(childFilter, innerQuery,
+ HasChildQueryBuilder.DEFAULT_MIN_CHILDREN, HasChildQueryBuilder.DEFAULT_MAX_CHILDREN,
+ fieldType.name(), score ? ScoreMode.Max : ScoreMode.None, fieldData, context.getSearchSimilarity());
+ } else {
+ if (ignoreUnmapped) {
+ return new MatchNoDocsQuery();
+ } else {
+ throw new QueryShardException(context, "[" + NAME + "] join field has no parent type configured");
+ }
+ }
+ }
+
+ private Query parentFieldDoToQuery(QueryShardContext context) throws IOException {
Query innerQuery;
String[] previousTypes = context.getTypes();
context.setTypes(type);
@@ -239,7 +270,7 @@ public class HasParentQueryBuilder extends AbstractQueryBuilder<HasParentQueryBu
innerQuery,
HasChildQueryBuilder.DEFAULT_MIN_CHILDREN,
HasChildQueryBuilder.DEFAULT_MAX_CHILDREN,
- type,
+ ParentFieldMapper.joinField(type),
score ? ScoreMode.Max : ScoreMode.None,
fieldData,
context.getSearchSimilarity());