20
20
package org .elasticsearch .index .mapper ;
21
21
22
22
import org .apache .lucene .analysis .TokenStream ;
23
+ import org .apache .lucene .analysis .core .WhitespaceAnalyzer ;
23
24
import org .apache .lucene .analysis .tokenattributes .CharTermAttribute ;
24
25
import org .apache .lucene .document .Field ;
25
26
import org .apache .lucene .document .SortedSetDocValuesField ;
35
36
import org .elasticsearch .common .xcontent .XContentBuilder ;
36
37
import org .elasticsearch .common .xcontent .XContentParser ;
37
38
import org .elasticsearch .common .xcontent .support .XContentMapValues ;
39
+ import org .elasticsearch .index .analysis .AnalyzerScope ;
40
+ import org .elasticsearch .index .analysis .IndexAnalyzers ;
38
41
import org .elasticsearch .index .analysis .NamedAnalyzer ;
39
42
import org .elasticsearch .index .fielddata .IndexFieldData ;
40
43
import org .elasticsearch .index .fielddata .plain .DocValuesIndexFieldData ;
@@ -73,6 +76,8 @@ public static class Builder extends FieldMapper.Builder<Builder, KeywordFieldMap
73
76
74
77
protected String nullValue = Defaults .NULL_VALUE ;
75
78
protected int ignoreAbove = Defaults .IGNORE_ABOVE ;
79
+ private IndexAnalyzers indexAnalyzers ;
80
+ private String normalizerName ;
76
81
77
82
public Builder (String name ) {
78
83
super (name , Defaults .FIELD_TYPE , Defaults .FIELD_TYPE );
@@ -106,15 +111,36 @@ public Builder eagerGlobalOrdinals(boolean eagerGlobalOrdinals) {
106
111
return builder ;
107
112
}
108
113
109
- public Builder normalizer (NamedAnalyzer normalizer ) {
110
- fieldType ().setNormalizer (normalizer );
111
- fieldType ().setSearchAnalyzer (normalizer );
114
+ public Builder splitQueriesOnWhitespace (boolean splitQueriesOnWhitespace ) {
115
+ fieldType ().setSplitQueriesOnWhitespace (splitQueriesOnWhitespace );
116
+ return builder ;
117
+ }
118
+
119
+ public Builder normalizer (IndexAnalyzers indexAnalyzers , String name ) {
120
+ this .indexAnalyzers = indexAnalyzers ;
121
+ this .normalizerName = name ;
112
122
return builder ;
113
123
}
114
124
115
125
@ Override
116
126
public KeywordFieldMapper build (BuilderContext context ) {
117
127
setupFieldType (context );
128
+ if (normalizerName != null ) {
129
+ NamedAnalyzer normalizer = indexAnalyzers .getNormalizer (normalizerName );
130
+ if (normalizer == null ) {
131
+ throw new MapperParsingException ("normalizer [" + normalizerName + "] not found for field [" + name + "]" );
132
+ }
133
+ fieldType ().setNormalizer (normalizer );
134
+ final NamedAnalyzer searchAnalyzer ;
135
+ if (fieldType ().splitQueriesOnWhitespace ) {
136
+ searchAnalyzer = indexAnalyzers .getWhitespaceNormalizer (normalizerName );
137
+ } else {
138
+ searchAnalyzer = normalizer ;
139
+ }
140
+ fieldType ().setSearchAnalyzer (searchAnalyzer );
141
+ } else if (fieldType ().splitQueriesOnWhitespace ) {
142
+ fieldType ().setSearchAnalyzer (new NamedAnalyzer ("whitespace" , AnalyzerScope .INDEX , new WhitespaceAnalyzer ()));
143
+ }
118
144
return new KeywordFieldMapper (
119
145
name , fieldType , defaultFieldType , ignoreAbove , includeInAll ,
120
146
context .indexSettings (), multiFieldsBuilder .build (this , context ), copyTo );
@@ -147,13 +173,12 @@ public Mapper.Builder<?,?> parse(String name, Map<String, Object> node, ParserCo
147
173
iterator .remove ();
148
174
} else if (propName .equals ("normalizer" )) {
149
175
if (propNode != null ) {
150
- NamedAnalyzer normalizer = parserContext .getIndexAnalyzers ().getNormalizer (propNode .toString ());
151
- if (normalizer == null ) {
152
- throw new MapperParsingException ("normalizer [" + propNode .toString () + "] not found for field [" + name + "]" );
153
- }
154
- builder .normalizer (normalizer );
176
+ builder .normalizer (parserContext .getIndexAnalyzers (), propNode .toString ());
155
177
}
156
178
iterator .remove ();
179
+ } else if (propName .equals ("split_queries_on_whitespace" )) {
180
+ builder .splitQueriesOnWhitespace (XContentMapValues .nodeBooleanValue (propNode , "split_queries_on_whitespace" ));
181
+ iterator .remove ();
157
182
}
158
183
}
159
184
return builder ;
@@ -163,6 +188,7 @@ public Mapper.Builder<?,?> parse(String name, Map<String, Object> node, ParserCo
163
188
public static final class KeywordFieldType extends StringFieldType {
164
189
165
190
private NamedAnalyzer normalizer = null ;
191
+ private boolean splitQueriesOnWhitespace ;
166
192
167
193
public KeywordFieldType () {
168
194
setIndexAnalyzer (Lucene .KEYWORD_ANALYZER );
@@ -172,6 +198,7 @@ public KeywordFieldType() {
172
198
protected KeywordFieldType (KeywordFieldType ref ) {
173
199
super (ref );
174
200
this .normalizer = ref .normalizer ;
201
+ this .splitQueriesOnWhitespace = splitQueriesOnWhitespace ;
175
202
}
176
203
177
204
public KeywordFieldType clone () {
@@ -183,7 +210,9 @@ public boolean equals(Object o) {
183
210
if (super .equals (o ) == false ) {
184
211
return false ;
185
212
}
186
- return Objects .equals (normalizer , ((KeywordFieldType ) o ).normalizer );
213
+ KeywordFieldType other = (KeywordFieldType ) o ;
214
+ return Objects .equals (normalizer , other .normalizer ) &&
215
+ splitQueriesOnWhitespace == other .splitQueriesOnWhitespace ;
187
216
}
188
217
189
218
@ Override
@@ -197,7 +226,7 @@ public void checkCompatibility(MappedFieldType otherFT, List<String> conflicts,
197
226
198
227
@ Override
199
228
public int hashCode () {
200
- return 31 * super .hashCode () + Objects .hashCode (normalizer );
229
+ return 31 * super .hashCode () + Objects .hash (normalizer , splitQueriesOnWhitespace );
201
230
}
202
231
203
232
@ Override
@@ -214,6 +243,15 @@ public void setNormalizer(NamedAnalyzer normalizer) {
214
243
this .normalizer = normalizer ;
215
244
}
216
245
246
+ public boolean splitQueriesOnWhitespace () {
247
+ return splitQueriesOnWhitespace ;
248
+ }
249
+
250
+ public void setSplitQueriesOnWhitespace (boolean splitQueriesOnWhitespace ) {
251
+ checkIfFrozen ();
252
+ this .splitQueriesOnWhitespace = splitQueriesOnWhitespace ;
253
+ }
254
+
217
255
@ Override
218
256
public Query existsQuery (QueryShardContext context ) {
219
257
if (hasDocValues ()) {
@@ -393,5 +431,9 @@ protected void doXContentBody(XContentBuilder builder, boolean includeDefaults,
393
431
} else if (includeDefaults ) {
394
432
builder .nullField ("normalizer" );
395
433
}
434
+
435
+ if (includeDefaults || fieldType ().splitQueriesOnWhitespace ) {
436
+ builder .field ("split_queries_on_whitespace" , fieldType ().splitQueriesOnWhitespace );
437
+ }
396
438
}
397
439
}
0 commit comments