Skip to content

Commit

Permalink
Convert percolator, murmur3 and histogram mappers to parametrized form (
Browse files Browse the repository at this point in the history
#63004)

Relates to #62988
  • Loading branch information
romseygeek committed Sep 29, 2020
1 parent a914d8b commit de08ba5
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 299 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.NumberFieldMapper;
import org.elasticsearch.index.mapper.ParametrizedFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.RangeFieldMapper;
import org.elasticsearch.index.mapper.RangeType;
Expand Down Expand Up @@ -96,9 +97,10 @@

import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder;

public class PercolatorFieldMapper extends FieldMapper {
public class PercolatorFieldMapper extends ParametrizedFieldMapper {

static final XContentType QUERY_BUILDER_CONTENT_TYPE = XContentType.SMILE;

static final Setting<Boolean> INDEX_MAP_UNMAPPED_FIELDS_AS_TEXT_SETTING = Setting.boolSetting(
"index.percolator.map_unmapped_fields_as_text", false, Setting.Property.IndexScope);
static final String CONTENT_TYPE = "percolator";
Expand All @@ -114,18 +116,30 @@ public class PercolatorFieldMapper extends FieldMapper {
static final String RANGE_FIELD_NAME = "range_field";
static final String MINIMUM_SHOULD_MATCH_FIELD_NAME = "minimum_should_match_field";

static class Builder extends FieldMapper.Builder<Builder> {
@Override
public ParametrizedFieldMapper.Builder getMergeBuilder() {
return new Builder(simpleName(), queryShardContext).init(this);
}

static class Builder extends ParametrizedFieldMapper.Builder {

private final Parameter<Map<String, String>> meta = Parameter.metaParam();

private final Supplier<QueryShardContext> queryShardContext;

Builder(String fieldName, Supplier<QueryShardContext> queryShardContext) {
super(fieldName, new FieldType());
super(fieldName);
this.queryShardContext = queryShardContext;
}

@Override
protected List<Parameter<?>> getParameters() {
return Arrays.asList(meta);
}

@Override
public PercolatorFieldMapper build(BuilderContext context) {
PercolatorFieldType fieldType = new PercolatorFieldType(buildFullName(context), meta);
PercolatorFieldType fieldType = new PercolatorFieldType(buildFullName(context), meta.getValue());
context.path().add(name());
KeywordFieldMapper extractedTermsField = createExtractQueryFieldBuilder(EXTRACTED_TERMS_FIELD_NAME, context);
fieldType.queryTermsField = extractedTermsField.fieldType();
Expand All @@ -142,8 +156,8 @@ public PercolatorFieldMapper build(BuilderContext context) {
fieldType.mapUnmappedFieldsAsText = getMapUnmappedFieldAsText(context.indexSettings());

context.path().remove();
return new PercolatorFieldMapper(name(), Builder.this.fieldType, fieldType,
multiFieldsBuilder.build(this, context), copyTo, queryShardContext, extractedTermsField,
return new PercolatorFieldMapper(name(), fieldType,
multiFieldsBuilder.build(this, context), copyTo.build(), queryShardContext, extractedTermsField,
extractionResultField, queryBuilderField, rangeFieldMapper, minimumShouldMatchFieldMapper,
getMapUnmappedFieldAsText(context.indexSettings()));
}
Expand Down Expand Up @@ -314,12 +328,12 @@ Tuple<List<BytesRef>, Map<String, List<byte[]>>> extractTermsAndRanges(IndexRead
private final RangeFieldMapper rangeFieldMapper;
private final boolean mapUnmappedFieldsAsText;

PercolatorFieldMapper(String simpleName, FieldType fieldType, MappedFieldType mappedFieldType,
PercolatorFieldMapper(String simpleName, MappedFieldType mappedFieldType,
MultiFields multiFields, CopyTo copyTo, Supplier<QueryShardContext> queryShardContext,
KeywordFieldMapper queryTermsField, KeywordFieldMapper extractionResultField,
BinaryFieldMapper queryBuilderField, RangeFieldMapper rangeFieldMapper,
NumberFieldMapper minimumShouldMatchFieldMapper, boolean mapUnmappedFieldsAsText) {
super(simpleName, fieldType, mappedFieldType, multiFields, copyTo);
super(simpleName, mappedFieldType, multiFields, copyTo);
this.queryShardContext = queryShardContext;
this.queryTermsField = queryTermsField;
this.extractionResultField = extractionResultField;
Expand Down Expand Up @@ -476,12 +490,7 @@ public Iterator<Mapper> iterator() {
}

@Override
protected void mergeOptions(FieldMapper other, List<String> conflicts) {

}

@Override
protected void parseCreateField(ParseContext context) throws IOException {
protected void parseCreateField(ParseContext context) {
throw new UnsupportedOperationException("should not be invoked");
}

Expand Down Expand Up @@ -548,14 +557,4 @@ static byte[] encodeRange(String rangeFieldName, byte[] minEncoded, byte[] maxEn
System.arraycopy(maxEncoded, 0, bytes, BinaryRange.BYTES + offset, maxEncoded.length);
return bytes;
}

@Override
protected boolean indexedByDefault() {
return false;
}

@Override
protected boolean docValuesByDefault() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,23 @@
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.ParametrizedFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.SourceValueFetcher;
import org.elasticsearch.index.mapper.TextSearchInfo;
import org.elasticsearch.index.mapper.TypeParsers;
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class Murmur3FieldMapper extends FieldMapper {
public class Murmur3FieldMapper extends ParametrizedFieldMapper {

public static final String CONTENT_TYPE = "murmur3";

Expand All @@ -60,40 +59,36 @@ public static class Defaults {
}
}

public static class Builder extends FieldMapper.Builder<Builder> {
private static Murmur3FieldMapper toType(FieldMapper in) {
return (Murmur3FieldMapper) in;
}

public static class Builder extends ParametrizedFieldMapper.Builder {

final Parameter<Boolean> stored = Parameter.storeParam(m -> toType(m).fieldType().isStored(), false);
final Parameter<Map<String, String>> meta = Parameter.metaParam();

public Builder(String name) {
super(name, Defaults.FIELD_TYPE);
builder = this;
super(name);
}

@Override
public Murmur3FieldMapper build(BuilderContext context) {
return new Murmur3FieldMapper(name, fieldType, new Murmur3FieldType(buildFullName(context), fieldType.stored(), meta),
multiFieldsBuilder.build(this, context), copyTo);
protected List<Parameter<?>> getParameters() {
return Arrays.asList(stored, meta);
}
}

public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder<?> parse(String name, Map<String, Object> node, ParserContext parserContext)
throws MapperParsingException {
Builder builder = new Builder(name);

// tweaking these settings is no longer allowed, the entire purpose of murmur3 fields is to store a hash
if (node.get("doc_values") != null) {
throw new MapperParsingException("Setting [doc_values] cannot be modified for field [" + name + "]");
}
if (node.get("index") != null) {
throw new MapperParsingException("Setting [index] cannot be modified for field [" + name + "]");
}

TypeParsers.parseField(builder, name, node, parserContext);

return builder;
public Murmur3FieldMapper build(BuilderContext context) {
return new Murmur3FieldMapper(
name,
new Murmur3FieldType(buildFullName(context), stored.getValue(), meta.getValue()),
multiFieldsBuilder.build(this, context),
copyTo.build());
}
}

public static TypeParser PARSER = new TypeParser((n, c) -> new Builder(n));

// this only exists so a check can be done to match the field type to using murmur3 hashing...
public static class Murmur3FieldType extends MappedFieldType {
private Murmur3FieldType(String name, boolean isStored, Map<String, String> meta) {
Expand All @@ -117,9 +112,16 @@ public Query termQuery(Object value, QueryShardContext context) {
}
}

protected Murmur3FieldMapper(String simpleName, FieldType fieldType, MappedFieldType mappedFieldType,
MultiFields multiFields, CopyTo copyTo) {
super(simpleName, fieldType, mappedFieldType, multiFields, copyTo);
protected Murmur3FieldMapper(String simpleName,
MappedFieldType mappedFieldType,
MultiFields multiFields,
CopyTo copyTo) {
super(simpleName, mappedFieldType, multiFields, copyTo);
}

@Override
public ParametrizedFieldMapper.Builder getMergeBuilder() {
return new Builder(simpleName()).init(this);
}

@Override
Expand All @@ -140,7 +142,7 @@ protected void parseCreateField(ParseContext context)
final BytesRef bytes = new BytesRef(value.toString());
final long hash = MurmurHash3.hash128(bytes.bytes, bytes.offset, bytes.length, 0, new MurmurHash3.Hash128()).h1;
context.doc().add(new SortedNumericDocValuesField(fieldType().name(), hash));
if (fieldType.stored()) {
if (fieldType().isStored()) {
context.doc().add(new StoredField(name(), hash));
}
}
Expand All @@ -159,13 +161,4 @@ protected String parseSourceValue(Object value) {
};
}

@Override
protected boolean indexedByDefault() {
return false;
}

@Override
protected void mergeOptions(FieldMapper other, List<String> conflicts) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@

package org.elasticsearch.plugin.mapper;

import java.util.Collections;
import java.util.Map;

import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.murmur3.Murmur3FieldMapper;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.plugins.Plugin;

import java.util.Collections;
import java.util.Map;

public class MapperMurmur3Plugin extends Plugin implements MapperPlugin {

@Override
public Map<String, Mapper.TypeParser> getMappers() {
return Collections.singletonMap(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser());
return Collections.singletonMap(Murmur3FieldMapper.CONTENT_TYPE, Murmur3FieldMapper.PARSER);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,22 @@
import org.apache.lucene.index.IndexableField;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapperTestCase2;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperTestCase;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.plugin.mapper.MapperMurmur3Plugin;
import org.elasticsearch.plugins.Plugin;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

import static org.hamcrest.Matchers.containsString;

public class Murmur3FieldMapperTests extends FieldMapperTestCase2<Murmur3FieldMapper.Builder> {
public class Murmur3FieldMapperTests extends MapperTestCase {

@Override
protected void writeFieldValue(XContentBuilder builder) throws IOException {
builder.value("value");
}

@Override
protected Set<String> unsupportedProperties() {
return org.elasticsearch.common.collect.Set.of("analyzer", "similarity", "doc_values", "index");
}

@Override
protected Collection<? extends Plugin> getPlugins() {
return org.elasticsearch.common.collect.List.of(new MapperMurmur3Plugin());
Expand All @@ -60,8 +51,8 @@ protected void minimalMapping(XContentBuilder b) throws IOException {
}

@Override
protected void registerParameters(ParameterChecker checker) {
// no parameters to configure
protected void registerParameters(ParameterChecker checker) throws IOException {
checker.registerConflictCheck("store", b -> b.field("store", true));
}

public void testDefaults() throws Exception {
Expand All @@ -75,38 +66,4 @@ public void testDefaults() throws Exception {
assertEquals(DocValuesType.SORTED_NUMERIC, field.fieldType().docValuesType());
}

public void testDocValuesSettingNotAllowed() throws Exception {
Exception e = expectThrows(
MapperParsingException.class,
() -> createMapperService(fieldMapping(b -> b.field("type", "murmur3").field("doc_values", false)))
);
assertThat(e.getMessage(), containsString("Setting [doc_values] cannot be modified"));

// even setting to the default is not allowed, the setting is invalid
e = expectThrows(
MapperParsingException.class,
() -> createMapperService(fieldMapping(b -> b.field("type", "murmur3").field("doc_values", true)))
);
assertThat(e.getMessage(), containsString("Setting [doc_values] cannot be modified"));
}

public void testIndexSettingNotAllowed() throws Exception {
Exception e = expectThrows(
MapperParsingException.class,
() -> createMapperService(fieldMapping(b -> b.field("type", "murmur3").field("index", "not_analyzed")))
);
assertThat(e.getMessage(), containsString("Setting [index] cannot be modified"));

// even setting to the default is not allowed, the setting is invalid
e = expectThrows(
MapperParsingException.class,
() -> createMapperService(fieldMapping(b -> b.field("type", "murmur3").field("index", "no")))
);
assertThat(e.getMessage(), containsString("Setting [index] cannot be modified"));
}

@Override
protected Murmur3FieldMapper.Builder newBuilder() {
return new Murmur3FieldMapper.Builder("murmur");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public List<Setting<?>> getSettings() {

@Override
public Map<String, Mapper.TypeParser> getMappers() {
return Collections.singletonMap(HistogramFieldMapper.CONTENT_TYPE, new HistogramFieldMapper.TypeParser());
return Collections.singletonMap(HistogramFieldMapper.CONTENT_TYPE, HistogramFieldMapper.PARSER);
}

@Override
Expand Down

0 comments on commit de08ba5

Please sign in to comment.