|
@@ -20,6 +20,7 @@
|
|
|
package org.elasticsearch.index.mapper;
|
|
|
|
|
|
import org.apache.lucene.analysis.TokenStream;
|
|
|
+import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
|
|
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
|
|
import org.apache.lucene.document.Field;
|
|
|
import org.apache.lucene.document.SortedSetDocValuesField;
|
|
@@ -35,6 +36,8 @@ import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
|
|
+import org.elasticsearch.index.analysis.AnalyzerScope;
|
|
|
+import org.elasticsearch.index.analysis.IndexAnalyzers;
|
|
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
|
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
|
|
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
|
|
@@ -73,6 +76,8 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
|
|
|
protected String nullValue = Defaults.NULL_VALUE;
|
|
|
protected int ignoreAbove = Defaults.IGNORE_ABOVE;
|
|
|
+ private IndexAnalyzers indexAnalyzers;
|
|
|
+ private String normalizerName;
|
|
|
|
|
|
public Builder(String name) {
|
|
|
super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE);
|
|
@@ -106,15 +111,36 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
return builder;
|
|
|
}
|
|
|
|
|
|
- public Builder normalizer(NamedAnalyzer normalizer) {
|
|
|
- fieldType().setNormalizer(normalizer);
|
|
|
- fieldType().setSearchAnalyzer(normalizer);
|
|
|
+ public Builder splitQueriesOnWhitespace(boolean splitQueriesOnWhitespace) {
|
|
|
+ fieldType().setSplitQueriesOnWhitespace(splitQueriesOnWhitespace);
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Builder normalizer(IndexAnalyzers indexAnalyzers, String name) {
|
|
|
+ this.indexAnalyzers = indexAnalyzers;
|
|
|
+ this.normalizerName = name;
|
|
|
return builder;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public KeywordFieldMapper build(BuilderContext context) {
|
|
|
setupFieldType(context);
|
|
|
+ if (normalizerName != null) {
|
|
|
+ NamedAnalyzer normalizer = indexAnalyzers.getNormalizer(normalizerName);
|
|
|
+ if (normalizer == null) {
|
|
|
+ throw new MapperParsingException("normalizer [" + normalizerName + "] not found for field [" + name + "]");
|
|
|
+ }
|
|
|
+ fieldType().setNormalizer(normalizer);
|
|
|
+ final NamedAnalyzer searchAnalyzer;
|
|
|
+ if (fieldType().splitQueriesOnWhitespace) {
|
|
|
+ searchAnalyzer = indexAnalyzers.getWhitespaceNormalizer(normalizerName);
|
|
|
+ } else {
|
|
|
+ searchAnalyzer = normalizer;
|
|
|
+ }
|
|
|
+ fieldType().setSearchAnalyzer(searchAnalyzer);
|
|
|
+ } else if (fieldType().splitQueriesOnWhitespace) {
|
|
|
+ fieldType().setSearchAnalyzer(new NamedAnalyzer("whitespace", AnalyzerScope.INDEX, new WhitespaceAnalyzer()));
|
|
|
+ }
|
|
|
return new KeywordFieldMapper(
|
|
|
name, fieldType, defaultFieldType, ignoreAbove,
|
|
|
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
@@ -147,13 +173,12 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
iterator.remove();
|
|
|
} else if (propName.equals("normalizer")) {
|
|
|
if (propNode != null) {
|
|
|
- NamedAnalyzer normalizer = parserContext.getIndexAnalyzers().getNormalizer(propNode.toString());
|
|
|
- if (normalizer == null) {
|
|
|
- throw new MapperParsingException("normalizer [" + propNode.toString() + "] not found for field [" + name + "]");
|
|
|
- }
|
|
|
- builder.normalizer(normalizer);
|
|
|
+ builder.normalizer(parserContext.getIndexAnalyzers(), propNode.toString());
|
|
|
}
|
|
|
iterator.remove();
|
|
|
+ } else if (propName.equals("split_queries_on_whitespace")) {
|
|
|
+ builder.splitQueriesOnWhitespace(XContentMapValues.nodeBooleanValue(propNode, "split_queries_on_whitespace"));
|
|
|
+ iterator.remove();
|
|
|
}
|
|
|
}
|
|
|
return builder;
|
|
@@ -163,6 +188,7 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
public static final class KeywordFieldType extends StringFieldType {
|
|
|
|
|
|
private NamedAnalyzer normalizer = null;
|
|
|
+ private boolean splitQueriesOnWhitespace;
|
|
|
|
|
|
public KeywordFieldType() {
|
|
|
setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
|
@@ -172,6 +198,7 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
protected KeywordFieldType(KeywordFieldType ref) {
|
|
|
super(ref);
|
|
|
this.normalizer = ref.normalizer;
|
|
|
+ this.splitQueriesOnWhitespace = splitQueriesOnWhitespace;
|
|
|
}
|
|
|
|
|
|
public KeywordFieldType clone() {
|
|
@@ -183,7 +210,9 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
if (super.equals(o) == false) {
|
|
|
return false;
|
|
|
}
|
|
|
- return Objects.equals(normalizer, ((KeywordFieldType) o).normalizer);
|
|
|
+ KeywordFieldType other = (KeywordFieldType) o;
|
|
|
+ return Objects.equals(normalizer, other.normalizer) &&
|
|
|
+ splitQueriesOnWhitespace == other.splitQueriesOnWhitespace;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -197,7 +226,7 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
|
|
|
@Override
|
|
|
public int hashCode() {
|
|
|
- return 31 * super.hashCode() + Objects.hashCode(normalizer);
|
|
|
+ return 31 * super.hashCode() + Objects.hash(normalizer, splitQueriesOnWhitespace);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -214,6 +243,15 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
this.normalizer = normalizer;
|
|
|
}
|
|
|
|
|
|
+ public boolean splitQueriesOnWhitespace() {
|
|
|
+ return splitQueriesOnWhitespace;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSplitQueriesOnWhitespace(boolean splitQueriesOnWhitespace) {
|
|
|
+ checkIfFrozen();
|
|
|
+ this.splitQueriesOnWhitespace = splitQueriesOnWhitespace;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public Query existsQuery(QueryShardContext context) {
|
|
|
if (hasDocValues()) {
|
|
@@ -263,7 +301,8 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
private int ignoreAbove;
|
|
|
|
|
|
protected KeywordFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType,
|
|
|
- int ignoreAbove, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
|
|
+ int ignoreAbove, Settings indexSettings,
|
|
|
+ MultiFields multiFields, CopyTo copyTo) {
|
|
|
super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo);
|
|
|
assert fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) <= 0;
|
|
|
this.ignoreAbove = ignoreAbove;
|
|
@@ -366,5 +405,9 @@ public final class KeywordFieldMapper extends FieldMapper {
|
|
|
} else if (includeDefaults) {
|
|
|
builder.nullField("normalizer");
|
|
|
}
|
|
|
+
|
|
|
+ if (includeDefaults || fieldType().splitQueriesOnWhitespace) {
|
|
|
+ builder.field("split_queries_on_whitespace", fieldType().splitQueriesOnWhitespace);
|
|
|
+ }
|
|
|
}
|
|
|
}
|