Browse Source

Rename index_prefix to index_prefixes (#30932)

This commit also adds index_prefixes tests to TextFieldMapperTests to ensure that cloning and wire-serialization work correctly
Alan Woodward 7 years ago
parent
commit
67905c85a5

+ 3 - 3
docs/reference/mapping/types/text.asciidoc

@@ -89,7 +89,7 @@ The following parameters are accepted by `text` fields:
     What information should be stored in the index, for search and highlighting purposes.
     Defaults to `positions`.
 
-<<index-prefix-config,`index_prefix`>>::
+<<index-prefix-config,`index_prefixes`>>::
 
     If enabled, term prefixes of between 2 and 5 characters are indexed into a
     separate field.  This allows prefix searches to run more efficiently, at
@@ -138,7 +138,7 @@ The following parameters are accepted by `text` fields:
 [[index-prefix-config]]
 ==== Index Prefix configuration
 
-Text fields may also index term prefixes to speed up prefix searches. The `index_prefix`
+Text fields may also index term prefixes to speed up prefix searches. The `index_prefixes`
 parameter is configured as below. Either or both of `min_chars` and `max_chars` may be excluded.
 Both values are treated as inclusive
 
@@ -151,7 +151,7 @@ PUT my_index
       "properties": {
         "full_name": {
           "type":  "text",
-          "index_prefix" : {
+          "index_prefixes" : {
             "min_chars" : 1,    <1>
             "max_chars" : 10    <2>
           }

+ 2 - 2
rest-api-spec/src/main/resources/rest-api-spec/test/search/190_index_prefix_search.yml

@@ -2,7 +2,7 @@
 "search with index prefixes":
   - skip:
       version: " - 6.99.99"
-      reason: index_prefix is only available as of 6.3.0
+      reason: index_prefixes is only available as of 6.3.0
   - do:
       indices.create:
         index:  test
@@ -12,7 +12,7 @@
               properties:
                 text:
                   type: text
-                  index_prefix:
+                  index_prefixes:
                     min_chars: 1
                     max_chars: 10
 

+ 30 - 6
server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java

@@ -156,7 +156,7 @@ public class TextFieldMapper extends FieldMapper {
             PrefixFieldMapper prefixMapper = null;
             if (prefixFieldType != null) {
                 if (fieldType().isSearchable() == false) {
-                    throw new IllegalArgumentException("Cannot set index_prefix on unindexed field [" + name() + "]");
+                    throw new IllegalArgumentException("Cannot set index_prefixes on unindexed field [" + name() + "]");
                 }
                 if (fieldType.indexOptions() == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) {
                     prefixFieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
@@ -203,7 +203,7 @@ public class TextFieldMapper extends FieldMapper {
                     builder.fielddataFrequencyFilter(minFrequency, maxFrequency, minSegmentSize);
                     DocumentMapperParser.checkNoRemainingFields(propName, frequencyFilter, parserContext.indexVersionCreated());
                     iterator.remove();
-                } else if (propName.equals("index_prefix")) {
+                } else if (propName.equals("index_prefixes")) {
                     Map<?, ?> indexPrefix = (Map<?, ?>) propNode;
                     int minChars = XContentMapValues.nodeIntegerValue(indexPrefix.remove("min_chars"),
                         Defaults.INDEX_PREFIX_MIN_CHARS);
@@ -243,7 +243,7 @@ public class TextFieldMapper extends FieldMapper {
         }
     }
 
-    private static final class PrefixFieldType extends StringFieldType {
+    static final class PrefixFieldType extends StringFieldType {
 
         final int minChars;
         final int maxChars;
@@ -268,14 +268,14 @@ public class TextFieldMapper extends FieldMapper {
         }
 
         void doXContent(XContentBuilder builder) throws IOException {
-            builder.startObject("index_prefix");
+            builder.startObject("index_prefixes");
             builder.field("min_chars", minChars);
             builder.field("max_chars", maxChars);
             builder.endObject();
         }
 
         @Override
-        public MappedFieldType clone() {
+        public PrefixFieldType clone() {
             return new PrefixFieldType(name(), minChars, maxChars);
         }
 
@@ -305,6 +305,22 @@ public class TextFieldMapper extends FieldMapper {
         public Query existsQuery(QueryShardContext context) {
             throw new UnsupportedOperationException();
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            if (!super.equals(o)) return false;
+            PrefixFieldType that = (PrefixFieldType) o;
+            return minChars == that.minChars &&
+                maxChars == that.maxChars;
+        }
+
+        @Override
+        public int hashCode() {
+
+            return Objects.hash(super.hashCode(), minChars, maxChars);
+        }
     }
 
     private static final class PrefixFieldMapper extends FieldMapper {
@@ -355,6 +371,9 @@ public class TextFieldMapper extends FieldMapper {
             this.fielddataMinFrequency = ref.fielddataMinFrequency;
             this.fielddataMaxFrequency = ref.fielddataMaxFrequency;
             this.fielddataMinSegmentSize = ref.fielddataMinSegmentSize;
+            if (ref.prefixFieldType != null) {
+                this.prefixFieldType = ref.prefixFieldType.clone();
+            }
         }
 
         public TextFieldType clone() {
@@ -368,6 +387,7 @@ public class TextFieldMapper extends FieldMapper {
             }
             TextFieldType that = (TextFieldType) o;
             return fielddata == that.fielddata
+                    && Objects.equals(prefixFieldType, that.prefixFieldType)
                     && fielddataMinFrequency == that.fielddataMinFrequency
                     && fielddataMaxFrequency == that.fielddataMaxFrequency
                     && fielddataMinSegmentSize == that.fielddataMinSegmentSize;
@@ -375,7 +395,7 @@ public class TextFieldMapper extends FieldMapper {
 
         @Override
         public int hashCode() {
-            return Objects.hash(super.hashCode(), fielddata,
+            return Objects.hash(super.hashCode(), fielddata, prefixFieldType,
                     fielddataMinFrequency, fielddataMaxFrequency, fielddataMinSegmentSize);
         }
 
@@ -420,6 +440,10 @@ public class TextFieldMapper extends FieldMapper {
             this.prefixFieldType = prefixFieldType;
         }
 
+        public PrefixFieldType getPrefixFieldType() {
+            return this.prefixFieldType;
+        }
+
         @Override
         public String typeName() {
             return CONTENT_TYPE;

+ 15 - 15
server/src/test/java/org/elasticsearch/index/mapper/TextFieldMapperTests.java

@@ -607,7 +607,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .field("index_options", "offsets")
                 .endObject().endObject().endObject().endObject());
 
@@ -623,7 +623,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .field("index_options", "positions")
                 .endObject().endObject().endObject().endObject());
 
@@ -640,7 +640,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .field("term_vector", "with_positions_offsets")
                 .endObject().endObject().endObject().endObject());
 
@@ -657,7 +657,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .field("term_vector", "with_positions")
                 .endObject().endObject().endObject().endObject());
 
@@ -682,7 +682,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 1)
                 .field("max_chars", 10)
                 .endObject()
@@ -716,7 +716,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .endObject().endObject()
                 .endObject().endObject());
             CompressedXContent json = new CompressedXContent(mapping);
@@ -741,7 +741,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 1)
                 .field("max_chars", 10)
                 .endObject()
@@ -760,7 +760,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 1)
                 .field("max_chars", 10)
                 .endObject()
@@ -783,7 +783,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 11)
                 .field("max_chars", 10)
                 .endObject()
@@ -800,7 +800,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 0)
                 .field("max_chars", 10)
                 .endObject()
@@ -817,7 +817,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .startObject("index_prefix")
+                .startObject("index_prefixes")
                 .field("min_chars", 1)
                 .field("max_chars", 25)
                 .endObject()
@@ -834,13 +834,13 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("analyzer", "english")
-                .field("index_prefix", (String) null)
+                .field("index_prefixes", (String) null)
                 .endObject().endObject()
                 .endObject().endObject());
             MapperParsingException e = expectThrows(MapperParsingException.class,
                 () -> parser.parse("type", new CompressedXContent(badConfigMapping))
             );
-            assertThat(e.getMessage(), containsString("[index_prefix] must not have a [null] value"));
+            assertThat(e.getMessage(), containsString("[index_prefixes] must not have a [null] value"));
         }
 
         {
@@ -848,13 +848,13 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
                 .startObject("properties").startObject("field")
                 .field("type", "text")
                 .field("index", "false")
-                .startObject("index_prefix").endObject()
+                .startObject("index_prefixes").endObject()
                 .endObject().endObject()
                 .endObject().endObject());
             IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
                 () -> parser.parse("type", new CompressedXContent(badConfigMapping))
             );
-            assertThat(e.getMessage(), containsString("Cannot set index_prefix on unindexed field [field]"));
+            assertThat(e.getMessage(), containsString("Cannot set index_prefixes on unindexed field [field]"));
         }
     }
 }

+ 13 - 0
server/src/test/java/org/elasticsearch/index/mapper/TextFieldTypeTests.java

@@ -71,6 +71,19 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
                 tft.setFielddataMinSegmentSize(1000);
             }
         });
+        addModifier(new Modifier("index_prefixes", true) {
+            @Override
+            public void modify(MappedFieldType ft) {
+                TextFieldMapper.TextFieldType tft = (TextFieldMapper.TextFieldType)ft;
+                TextFieldMapper.PrefixFieldType pft = tft.getPrefixFieldType();
+                if (pft == null) {
+                    tft.setPrefixFieldType(new TextFieldMapper.PrefixFieldType(ft.name(), 3, 3));
+                }
+                else {
+                    tft.setPrefixFieldType(null);
+                }
+            }
+        });
     }
 
     public void testTermQuery() {