synonymMaps = Arrays.stream(searchableField.synonymMapNames())
+ .filter(synonym -> !synonym.trim().isEmpty())
+ .collect(Collectors.toList());
+ searchField.setSynonymMapNames(synonymMaps);
+ }
+
return searchField;
}
@@ -318,11 +368,9 @@ private static void validateType(Type type, boolean hasArrayOrCollectionWrapped)
if (!(type instanceof ParameterizedType)) {
if (UNSUPPORTED_TYPES.contains(type)) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException(
- String.format("Type '%s' is not supported. "
- + "Please use @FieldIgnore to exclude the field "
- + "and manually build SearchField to the list if the field is needed. %n"
- + "For more information, refer to link: aka.ms/azsdk/java/search/fieldbuilder",
- type.getTypeName())));
+ "Type '" + type.getTypeName() + "' is not supported. Please use @FieldIgnore to exclude the field "
+ + "and manually build SearchField to the list if the field is needed. For more information, "
+ + "refer to link: aka.ms/azsdk/java/search/fieldbuilder"));
}
return;
}
@@ -333,13 +381,13 @@ private static void validateType(Type type, boolean hasArrayOrCollectionWrapped)
}
if (hasArrayOrCollectionWrapped) {
- throw LOGGER.logExceptionAsError(new IllegalArgumentException(
- "Only single-dimensional array is supported."));
+ throw LOGGER.logExceptionAsError(
+ new IllegalArgumentException("Only single-dimensional array is supported."));
}
if (!List.class.isAssignableFrom((Class>) parameterizedType.getRawType())) {
- throw LOGGER.logExceptionAsError(new IllegalArgumentException(
- String.format("Collection type %s is not supported", type.getTypeName())));
+ throw LOGGER.logExceptionAsError(
+ new IllegalArgumentException("Collection type '" + type.getTypeName() + "' is not supported"));
}
}
diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java
index cec17d813d595..b5ee7018909c4 100644
--- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java
+++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchableField.java
@@ -5,6 +5,7 @@
import com.azure.search.documents.indexes.models.FieldBuilderOptions;
import com.azure.search.documents.indexes.models.LexicalAnalyzerName;
+import com.azure.search.documents.indexes.models.LexicalNormalizerName;
import com.azure.search.documents.indexes.models.SearchField;
import com.azure.search.documents.indexes.models.SynonymMap;
@@ -58,27 +59,35 @@
/**
* A {@link LexicalAnalyzerName} to associate as the search and index analyzer for the {@link SearchField field}.
*
- * @return The {@link LexicalAnalyzerName} that will be associated as the search and index analyzer for the {@link
- * SearchField field}.
+ * @return The {@link LexicalAnalyzerName} that will be associated as the search and index analyzer for the
+ * {@link SearchField field}.
*/
String analyzerName() default "";
/**
* A {@link LexicalAnalyzerName} to associate as the search analyzer for the {@link SearchField field}.
*
- * @return The {@link LexicalAnalyzerName} that will be associated as the search analyzer for the {@link SearchField
- * field}.
+ * @return The {@link LexicalAnalyzerName} that will be associated as the search analyzer for the
+ * {@link SearchField field}.
*/
String searchAnalyzerName() default "";
/**
* A {@link LexicalAnalyzerName} to associate as the index analyzer for the {@link SearchField field}.
*
- * @return The {@link LexicalAnalyzerName} that will be associated as the index analyzer for the {@link SearchField
- * field}.
+ * @return The {@link LexicalAnalyzerName} that will be associated as the index analyzer for the
+ * {@link SearchField field}.
*/
String indexAnalyzerName() default "";
+ /**
+ * A {@link LexicalNormalizerName} to associate as the normalizer for the {@link SearchField field}.
+ *
+ * @return The {@link LexicalNormalizerName} that will be associated as the normalizer for the
+ * {@link SearchField field}.
+ */
+ String normalizerName() default "";
+
/**
* A list of {@link SynonymMap} names to be associated with the {@link SearchField field}.
*
diff --git a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java
index 98d4609465747..aa2f43edf7f0c 100644
--- a/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java
+++ b/sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SimpleField.java
@@ -4,6 +4,7 @@
package com.azure.search.documents.indexes;
import com.azure.search.documents.indexes.models.FieldBuilderOptions;
+import com.azure.search.documents.indexes.models.LexicalNormalizerName;
import com.azure.search.documents.indexes.models.SearchField;
import java.lang.annotation.ElementType;
@@ -52,4 +53,12 @@
* @return A flag indicating if the field or method should generate as a filterable {@link SearchField field}.
*/
boolean isFilterable() default false;
+
+ /**
+ * A {@link LexicalNormalizerName} to associate as the normalizer for the {@link SearchField field}.
+ *
+ * @return The {@link LexicalNormalizerName} that will be associated as the normalizer for the
+ * {@link SearchField field}.
+ */
+ String normalizerName() default "";
}
diff --git a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java
index c6ddf835a390f..309fed997dead 100644
--- a/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java
+++ b/sdk/search/azure-search-documents/src/test/java/com/azure/search/documents/indexes/FieldBuilderTests.java
@@ -5,6 +5,7 @@
import com.azure.core.models.GeoPoint;
import com.azure.search.documents.TestHelpers;
+import com.azure.search.documents.indexes.models.LexicalNormalizerName;
import com.azure.search.documents.indexes.models.SearchField;
import com.azure.search.documents.indexes.models.SearchFieldDataType;
import com.azure.search.documents.test.environment.models.HotelAnalyzerException;
@@ -18,6 +19,8 @@
import com.azure.search.documents.test.environment.models.HotelWithIgnoredFields;
import com.azure.search.documents.test.environment.models.HotelWithUnsupportedField;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import java.time.OffsetDateTime;
import java.util.Arrays;
@@ -255,6 +258,43 @@ public void unsupportedFields() {
assertExceptionMassageAndDataType(exception, null, "is not supported");
}
+ @Test
+ public void validNormalizerField() {
+ List fields = SearchIndexClient.buildSearchFields(ValidNormalizer.class, null);
+
+ assertEquals(1, fields.size());
+
+ SearchField normalizerField = fields.get(0);
+ assertEquals(LexicalNormalizerName.STANDARD, normalizerField.getNormalizerName());
+ }
+
+ @SuppressWarnings("unused")
+ public static final class ValidNormalizer {
+ @SimpleField(normalizerName = "standard", isFilterable = true)
+ public String validNormalizer;
+ }
+
+ @ParameterizedTest
+ @ValueSource(classes = { NonStringNormalizer.class, MissingFunctionalityNormalizer.class })
+ public void invalidNormalizerField(Class> type) {
+ RuntimeException ex = assertThrows(RuntimeException.class,
+ () -> SearchIndexClient.buildSearchFields(type, null));
+
+ assertTrue(ex.getMessage().contains("A field with a normalizer name"));
+ }
+
+ @SuppressWarnings("unused")
+ public static final class NonStringNormalizer {
+ @SimpleField(normalizerName = "standard")
+ public int wrongTypeForNormalizer;
+ }
+
+ @SuppressWarnings("unused")
+ public static final class MissingFunctionalityNormalizer {
+ @SimpleField(normalizerName = "standard")
+ public String rightTypeWrongFunctionality;
+ }
+
private void assertListFieldEquals(List expected, List actual) {
assertEquals(expected.size(), actual.size());
for (int i = 0; i < expected.size(); i++) {