diff --git a/sdk/search/Azure.Search.Documents/Directory.Build.props b/sdk/search/Azure.Search.Documents/Directory.Build.props index 81e574947ae70..082b272322051 100644 --- a/sdk/search/Azure.Search.Documents/Directory.Build.props +++ b/sdk/search/Azure.Search.Documents/Directory.Build.props @@ -10,17 +10,10 @@ $(UseAzureCoreExperimental) EXPERIMENTAL_SPATIAL;$(DefineConstants) - - true - EXPERIMENTAL_SERIALIZER;$(DefineConstants) - $(UseAzureCoreExperimental) EXPERIMENTAL_DYNAMIC;$(DefineConstants) - true - EXPERIMENTAL_FIELDBUILDER;$(DefineConstants) - true $(UseProjectReferenceToAzureClients) diff --git a/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj b/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj index 48d76d8a6e849..af010264ec490 100644 --- a/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj +++ b/sdk/search/Azure.Search.Documents/src/Azure.Search.Documents.csproj @@ -16,15 +16,6 @@ $(NoWarn);AZC0007;AZC0004;AZC0001 - - - - - - - - - diff --git a/sdk/search/Azure.Search.Documents/src/Indexes/FieldBuilder.cs b/sdk/search/Azure.Search.Documents/src/Indexes/FieldBuilder.cs index 42d695aa80ce1..e01a7dcb6055c 100644 --- a/sdk/search/Azure.Search.Documents/src/Indexes/FieldBuilder.cs +++ b/sdk/search/Azure.Search.Documents/src/Indexes/FieldBuilder.cs @@ -9,9 +9,7 @@ using System.Linq; using System.Reflection; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif using Azure.Search.Documents.Indexes.Models; #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; diff --git a/sdk/search/Azure.Search.Documents/src/Indexes/Models/LexicalAnalyzerName.cs b/sdk/search/Azure.Search.Documents/src/Indexes/Models/LexicalAnalyzerName.cs index 6e455d1125252..9fc3dabfda5aa 100644 --- a/sdk/search/Azure.Search.Documents/src/Indexes/Models/LexicalAnalyzerName.cs +++ b/sdk/search/Azure.Search.Documents/src/Indexes/Models/LexicalAnalyzerName.cs @@ -5,7 +5,6 @@ namespace Azure.Search.Documents.Indexes.Models { public readonly partial struct LexicalAnalyzerName { -#if EXPERIMENTAL_FIELDBUILDER #pragma warning disable CA1034 // Nested types should not be visible /// /// The values of all declared properties as string constants. @@ -201,6 +200,5 @@ public static class Values public const string Whitespace = LexicalAnalyzerName.WhitespaceValue; } #pragma warning restore CA1034 // Nested types should not be visible -#endif } } diff --git a/sdk/search/Azure.Search.Documents/src/Indexes/Models/SearchIndex.cs b/sdk/search/Azure.Search.Documents/src/Indexes/Models/SearchIndex.cs index 899db7fd762f3..eeaf6458f44ba 100644 --- a/sdk/search/Azure.Search.Documents/src/Indexes/Models/SearchIndex.cs +++ b/sdk/search/Azure.Search.Documents/src/Indexes/Models/SearchIndex.cs @@ -75,7 +75,6 @@ public SearchIndex(string name, IEnumerable fields) /// public IList CharFilters { get; } -#if EXPERIMENTAL_FIELDBUILDER /// /// Gets or sets the fields in the index. /// Use to define fields based on a model class, @@ -126,44 +125,6 @@ public SearchIndex(string name, IEnumerable fields) /// }; /// /// -#else - /// - /// Gets or sets the fields in the index. - /// Use , , and to manually define fields. - /// Index fields have many constraints that are not validated with until the index is created on the server. - /// - /// - /// You can create fields manually using helper classes: - /// - /// SearchIndex index = new SearchIndex("hotels") - /// { - /// Fields = - /// { - /// new SimpleField("hotelId", SearchFieldDataType.String) { IsKey = true, IsFilterable = true, IsSortable = true }, - /// new SearchableField("hotelName") { IsFilterable = true, IsSortable = true }, - /// new SearchableField("description") { AnalyzerName = LexicalAnalyzerName.EnLucene }, - /// new SearchableField("tags", collection: true) { IsFilterable = true, IsFacetable = true }, - /// new ComplexField("address") - /// { - /// Fields = - /// { - /// new SearchableField("streetAddress"), - /// new SearchableField("city") { IsFilterable = true, IsSortable = true, IsFacetable = true }, - /// new SearchableField("stateProvince") { IsFilterable = true, IsSortable = true, IsFacetable = true }, - /// new SearchableField("country") { IsFilterable = true, IsSortable = true, IsFacetable = true }, - /// new SearchableField("postalCode") { IsFilterable = true, IsSortable = true, IsFacetable = true } - /// } - /// } - /// }, - /// Suggesters = - /// { - /// // Suggest query terms from the hotelName field. - /// new SearchSuggester("sg", "hotelName") - /// } - /// }; - /// - /// -#endif public IList Fields { get => _fields; diff --git a/sdk/search/Azure.Search.Documents/src/Indexes/SearchIndexClient.cs b/sdk/search/Azure.Search.Documents/src/Indexes/SearchIndexClient.cs index b260bd6b6058c..48224f5412632 100644 --- a/sdk/search/Azure.Search.Documents/src/Indexes/SearchIndexClient.cs +++ b/sdk/search/Azure.Search.Documents/src/Indexes/SearchIndexClient.cs @@ -8,9 +8,7 @@ using System.Threading.Tasks; using Azure.Core; using Azure.Core.Pipeline; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif using Azure.Search.Documents.Indexes.Models; namespace Azure.Search.Documents.Indexes @@ -23,9 +21,7 @@ public class SearchIndexClient private readonly HttpPipeline _pipeline; private readonly ClientDiagnostics _clientDiagnostics; private readonly SearchClientOptions.ServiceVersion _version; -#if EXPERIMENTAL_SERIALIZER private readonly ObjectSerializer _serializer; -#endif private ServiceRestClient _serviceClient; private IndexesRestClient _indexesClient; @@ -76,9 +72,7 @@ public SearchIndexClient( options ??= new SearchClientOptions(); Endpoint = endpoint; -#if EXPERIMENTAL_SERIALIZER _serializer = options.Serializer; -#endif _clientDiagnostics = new ClientDiagnostics(options); _pipeline = options.Build(credential); _version = options.Version; @@ -146,9 +140,7 @@ public virtual SearchClient GetSearchClient(string indexName) return new SearchClient( Endpoint, indexName, -#if EXPERIMENTAL_SERIALIZER _serializer, -#endif _pipeline, _clientDiagnostics, _version); diff --git a/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsAction{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsAction{T}.cs index 6eaee9c46128c..8c179af42716b 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsAction{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsAction{T}.cs @@ -8,9 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -79,9 +77,7 @@ public IndexDocumentsAction(IndexActionType type, T doc) /// A task representing the serialization. internal async Task SerializeAsync( Utf8JsonWriter writer, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif JsonSerializerOptions options, bool async, CancellationToken cancellationToken) @@ -97,7 +93,6 @@ internal async Task SerializeAsync( // HACK: Serialize the user's model, parse it, and then write each // of its properties as if they were our own. byte[] json; -#if EXPERIMENTAL_SERIALIZER if (serializer != null) { using MemoryStream stream = new MemoryStream(); @@ -113,11 +108,8 @@ internal async Task SerializeAsync( } else { -#endif json = JsonSerializer.SerializeToUtf8Bytes(Document, options); -#if EXPERIMENTAL_SERIALIZER } -#endif using JsonDocument nested = JsonDocument.Parse(json); foreach (JsonProperty property in nested.RootElement.EnumerateObject()) { diff --git a/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsBatch{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsBatch{T}.cs index 4bf46ff31cbae..fab3601285e3c 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsBatch{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/IndexDocumentsBatch{T}.cs @@ -8,9 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -77,9 +75,7 @@ internal IndexDocumentsBatch(IndexActionType type, IEnumerable documents) /// A task representing the serialization. internal async Task SerializeAsync( Utf8JsonWriter writer, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif JsonSerializerOptions options, bool async, CancellationToken cancellationToken) @@ -93,9 +89,7 @@ internal async Task SerializeAsync( { await action.SerializeAsync( writer, -#if EXPERIMENTAL_SERIALIZER serializer, -#endif options, async, cancellationToken) diff --git a/sdk/search/Azure.Search.Documents/src/Models/SearchResults{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/SearchResults{T}.cs index 282f866651670..0dd208a6cb197 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/SearchResults{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/SearchResults{T}.cs @@ -11,9 +11,7 @@ using System.Threading.Tasks; using Azure.Core; using Azure.Core.Pipeline; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -167,9 +165,7 @@ await _pagingClient.SearchAsync( /// Deserialized SearchResults. internal static async Task> DeserializeAsync( Stream json, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif bool async, CancellationToken cancellationToken) #pragma warning restore CS1572 @@ -240,9 +236,7 @@ await JsonDocument.ParseAsync(json, cancellationToken: cancellationToken).Config { SearchResult result = await SearchResult.DeserializeAsync( element, -#if EXPERIMENTAL_SERIALIZER serializer, -#endif defaultSerializerOptions, async, cancellationToken) diff --git a/sdk/search/Azure.Search.Documents/src/Models/SearchResult{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/SearchResult{T}.cs index e34663d6ed324..ee3fcc4a837b7 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/SearchResult{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/SearchResult{T}.cs @@ -8,9 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -70,9 +68,7 @@ internal SearchResult() { } /// Deserialized SearchResults. internal static async Task> DeserializeAsync( JsonElement element, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif JsonSerializerOptions options, bool async, CancellationToken cancellationToken) @@ -104,7 +100,6 @@ internal static async Task> DeserializeAsync( } // Deserialize the model -#if EXPERIMENTAL_SERIALIZER if (serializer != null) { using Stream stream = element.ToStream(); @@ -115,7 +110,6 @@ internal static async Task> DeserializeAsync( } else { -#endif T document; if (async) { @@ -127,9 +121,7 @@ internal static async Task> DeserializeAsync( document = JsonSerializer.Deserialize(element.GetRawText(), options); } result.Document = document; -#if EXPERIMENTAL_SERIALIZER } -#endif return result; } diff --git a/sdk/search/Azure.Search.Documents/src/Models/SearchSuggestion{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/SearchSuggestion{T}.cs index ecbd9bde44464..09e7d198b48ba 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/SearchSuggestion{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/SearchSuggestion{T}.cs @@ -7,9 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -62,9 +60,7 @@ internal SearchSuggestion() { } /// Deserialized SearchSuggestion. internal static async Task> DeserializeAsync( JsonElement element, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif JsonSerializerOptions options, bool async, CancellationToken cancellationToken) @@ -83,7 +79,6 @@ internal static async Task> DeserializeAsync( } // Deserialize the model -#if EXPERIMENTAL_SERIALIZER if (serializer != null) { using Stream stream = element.ToStream(); @@ -94,7 +89,6 @@ internal static async Task> DeserializeAsync( } else { -#endif T document; if (async) { @@ -106,9 +100,7 @@ internal static async Task> DeserializeAsync( document = JsonSerializer.Deserialize(element.GetRawText(), options); } suggestion.Document = document; -#if EXPERIMENTAL_SERIALIZER } -#endif return suggestion; } diff --git a/sdk/search/Azure.Search.Documents/src/Models/SuggestResults{T}.cs b/sdk/search/Azure.Search.Documents/src/Models/SuggestResults{T}.cs index d318fc54d9a32..a018a354d678a 100644 --- a/sdk/search/Azure.Search.Documents/src/Models/SuggestResults{T}.cs +++ b/sdk/search/Azure.Search.Documents/src/Models/SuggestResults{T}.cs @@ -8,9 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -62,9 +60,7 @@ internal SuggestResults() { } /// Deserialized SuggestResults. internal static async Task> DeserializeAsync( Stream json, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif bool async, CancellationToken cancellationToken) #pragma warning restore CS1572 @@ -91,9 +87,7 @@ await JsonDocument.ParseAsync(json, cancellationToken: cancellationToken).Config { SearchSuggestion suggestion = await SearchSuggestion.DeserializeAsync( element, -#if EXPERIMENTAL_SERIALIZER serializer, -#endif defaultSerializerOptions, async, cancellationToken) diff --git a/sdk/search/Azure.Search.Documents/src/SearchClient.cs b/sdk/search/Azure.Search.Documents/src/SearchClient.cs index d767825b1d310..c0c0d67b18ab2 100644 --- a/sdk/search/Azure.Search.Documents/src/SearchClient.cs +++ b/sdk/search/Azure.Search.Documents/src/SearchClient.cs @@ -9,9 +9,7 @@ using System.Threading.Tasks; using Azure.Core; using Azure.Core.Pipeline; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Models; @@ -50,13 +48,11 @@ public class SearchClient /// public virtual string IndexName { get; } -#if EXPERIMENTAL_SERIALIZER /// /// Gets an that can be used to /// customize the serialization of strongly typed models. /// private ObjectSerializer Serializer { get; } -#endif /// /// Gets the authenticated used for sending @@ -170,9 +166,7 @@ public SearchClient( options ??= new SearchClientOptions(); Endpoint = endpoint; IndexName = indexName; -#if EXPERIMENTAL_SERIALIZER Serializer = options.Serializer; -#endif ClientDiagnostics = new ClientDiagnostics(options); Pipeline = options.Build(credential); Version = options.Version; @@ -214,9 +208,7 @@ public SearchClient( internal SearchClient( Uri endpoint, string indexName, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif HttpPipeline pipeline, ClientDiagnostics diagnostics, SearchClientOptions.ServiceVersion version) @@ -233,9 +225,7 @@ internal SearchClient( Endpoint = endpoint; IndexName = indexName; -#if EXPERIMENTAL_SERIALIZER Serializer = serializer; -#endif ClientDiagnostics = diagnostics; Pipeline = pipeline; Version = version; @@ -602,9 +592,7 @@ private async Task> GetDocumentInternal( case 200: { T value = await message.Response.ContentStream.DeserializeAsync( -#if EXPERIMENTAL_SERIALIZER Serializer, -#endif async, cancellationToken) .ConfigureAwait(false); @@ -789,9 +777,7 @@ private async Task>> SearchInternal( // Deserialize the results SearchResults results = await SearchResults.DeserializeAsync( message.Response.ContentStream, -#if EXPERIMENTAL_SERIALIZER Serializer, -#endif async, cancellationToken) .ConfigureAwait(false); @@ -961,9 +947,7 @@ private async Task>> SuggestInternal( { SuggestResults suggestions = await SuggestResults.DeserializeAsync( message.Response.ContentStream, -#if EXPERIMENTAL_SERIALIZER Serializer, -#endif async, cancellationToken) .ConfigureAwait(false); @@ -1238,9 +1222,7 @@ private async Task> IndexDocumentsInternal( Utf8JsonRequestContent content = new Utf8JsonRequestContent(); await batch.SerializeAsync( content.JsonWriter, -#if EXPERIMENTAL_SERIALIZER Serializer, -#endif JsonSerialization.SerializerOptions, async, cancellationToken) diff --git a/sdk/search/Azure.Search.Documents/src/SearchClientOptions.cs b/sdk/search/Azure.Search.Documents/src/SearchClientOptions.cs index 6fe535fb94c71..aa8956285e448 100644 --- a/sdk/search/Azure.Search.Documents/src/SearchClientOptions.cs +++ b/sdk/search/Azure.Search.Documents/src/SearchClientOptions.cs @@ -5,9 +5,7 @@ using System.Diagnostics; using Azure.Core; using Azure.Core.Pipeline; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #pragma warning disable SA1402 // File may only contain a single type @@ -54,7 +52,6 @@ public enum ServiceVersion /// public ServiceVersion Version { get; } -#if EXPERIMENTAL_SERIALIZER /// /// Gets or sets an that can be used to /// customize the serialization of strongly typed models. The @@ -62,7 +59,6 @@ public enum ServiceVersion /// will be used if no value is provided. /// public ObjectSerializer Serializer { get; set; } -#endif /// /// Initializes a new instance of the diff --git a/sdk/search/Azure.Search.Documents/src/Serialization/JsonSerialization.cs b/sdk/search/Azure.Search.Documents/src/Serialization/JsonSerialization.cs index b786d0bc53d67..4a905ec23bad2 100644 --- a/sdk/search/Azure.Search.Documents/src/Serialization/JsonSerialization.cs +++ b/sdk/search/Azure.Search.Documents/src/Serialization/JsonSerialization.cs @@ -10,9 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core.Pipeline; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; #endif @@ -349,9 +347,7 @@ public static void WriteSearchDocument( /// A deserialized object. public static async Task DeserializeAsync( this Stream json, -#if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, -#endif bool async, CancellationToken cancellationToken) #pragma warning restore CS1572 @@ -360,14 +356,12 @@ public static async Task DeserializeAsync( { return default; } -#if EXPERIMENTAL_SERIALIZER else if (serializer != null) { return async ? (T)await serializer.DeserializeAsync(json, typeof(T), cancellationToken).ConfigureAwait(false) : (T)serializer.Deserialize(json, typeof(T), cancellationToken); } -#endif else if (async) { return await JsonSerializer.DeserializeAsync( diff --git a/sdk/search/Azure.Search.Documents/tests/Azure.Search.Documents.Tests.csproj b/sdk/search/Azure.Search.Documents/tests/Azure.Search.Documents.Tests.csproj index 859ff58e05636..0782670cf243c 100644 --- a/sdk/search/Azure.Search.Documents/tests/Azure.Search.Documents.Tests.csproj +++ b/sdk/search/Azure.Search.Documents/tests/Azure.Search.Documents.Tests.csproj @@ -40,16 +40,6 @@ - - - - - - - - - - diff --git a/sdk/search/Azure.Search.Documents/tests/DocumentOperations/IndexingTests.cs b/sdk/search/Azure.Search.Documents/tests/DocumentOperations/IndexingTests.cs index 90fa45b81efd4..e281475339f20 100644 --- a/sdk/search/Azure.Search.Documents/tests/DocumentOperations/IndexingTests.cs +++ b/sdk/search/Azure.Search.Documents/tests/DocumentOperations/IndexingTests.cs @@ -7,9 +7,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; #endif @@ -423,16 +421,13 @@ public async Task StaticDocuments() Assert.AreEqual(3L, count); } -#if EXPERIMENTAL_SERIALIZER [Test] -#endif public async Task StaticDocumentsWithCustomSerializer() { await using SearchResources resources = await SearchResources.CreateWithEmptyHotelsIndexAsync(this); SearchClient client = resources.GetSearchClient( new SearchClientOptions() { -#if EXPERIMENTAL_SERIALIZER Serializer = new JsonObjectSerializer( new JsonSerializerOptions() { @@ -444,7 +439,6 @@ public async Task StaticDocumentsWithCustomSerializer() #endif } }) -#endif }); UncasedHotel expected = new UncasedHotel { diff --git a/sdk/search/Azure.Search.Documents/tests/DocumentOperations/SearchTests.cs b/sdk/search/Azure.Search.Documents/tests/DocumentOperations/SearchTests.cs index 0be5ee9280fc5..9682981da0aff 100644 --- a/sdk/search/Azure.Search.Documents/tests/DocumentOperations/SearchTests.cs +++ b/sdk/search/Azure.Search.Documents/tests/DocumentOperations/SearchTests.cs @@ -6,9 +6,7 @@ using System.Linq; using System.Text.Json; using System.Threading.Tasks; -#if EXPERIMENTAL_SERIALIZER using Azure.Core.Serialization; -#endif #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; #endif @@ -166,9 +164,7 @@ public async Task StaticDocuments() } } -#if EXPERIMENTAL_SERIALIZER [Test] -#endif public async Task StaticDocumentsWithCustomSerializer() { await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this); @@ -176,7 +172,6 @@ public async Task StaticDocumentsWithCustomSerializer() SearchClient client = resources.GetQueryClient( new SearchClientOptions() { -#if EXPERIMENTAL_SERIALIZER Serializer = new JsonObjectSerializer( new JsonSerializerOptions() { @@ -188,7 +183,6 @@ public async Task StaticDocumentsWithCustomSerializer() #endif } }) -#endif }); SearchResults response = await client.SearchAsync("*"); Assert.IsNull(response.TotalCount); diff --git a/sdk/search/Azure.Search.Documents/tests/FieldBuilderTests.cs b/sdk/search/Azure.Search.Documents/tests/FieldBuilderTests.cs index b58dd4469f368..a7e5d9faba4c0 100644 --- a/sdk/search/Azure.Search.Documents/tests/FieldBuilderTests.cs +++ b/sdk/search/Azure.Search.Documents/tests/FieldBuilderTests.cs @@ -7,9 +7,6 @@ using System.Text.Json.Serialization; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif using NUnit.Framework; using KeyFieldAttribute = System.ComponentModel.DataAnnotations.KeyAttribute; @@ -362,7 +359,6 @@ public void NestedKeyAttributesAreIgnored() { var expectedFields = new SearchField[] { -#if EXPERIMENTAL_FIELDBUILDER new SimpleField(nameof(ModelWithNestedKey.ID), SearchFieldDataType.String) { IsKey = true }, new ComplexField(nameof(ModelWithNestedKey.Inner)) { @@ -374,17 +370,6 @@ public void NestedKeyAttributesAreIgnored() new SimpleField(nameof(InnerModelWithKey.OtherField), SearchFieldDataType.Int32) { IsFilterable = true }, } } -#else - new SearchField(nameof(ModelWithNestedKey.ID), SearchFieldDataType.String) { IsKey = true }, - new SearchField(nameof(ModelWithNestedKey.Inner), SearchFieldDataType.Complex) - { - Fields = - { - new SearchField(nameof(InnerModelWithKey.InnerID), SearchFieldDataType.String), - new SearchField(nameof(InnerModelWithKey.OtherField), SearchFieldDataType.Int32) { IsFilterable = true }, - } - } -#endif }; IList actualFields = BuildForType(typeof(ModelWithNestedKey)); @@ -397,7 +382,6 @@ public void PropertiesMarkedAsIgnoredAreIgnored() { var expectedFields = new SearchField[] { -#if EXPERIMENTAL_FIELDBUILDER new SimpleField(nameof(ModelWithNestedKey.ID), SearchFieldDataType.String) { IsKey = true }, new ComplexField(nameof(ModelWithNestedKey.Inner), collection: true) { @@ -407,16 +391,6 @@ public void PropertiesMarkedAsIgnoredAreIgnored() new SimpleField(nameof(InnerModelWithIgnoredProperties.OtherField), SearchFieldDataType.Int32) { IsFilterable = true }, } } -#else - new SearchField(nameof(ModelWithNestedKey.ID), SearchFieldDataType.String) { IsKey = true }, - new SearchField(nameof(ModelWithNestedKey.Inner), SearchFieldDataType.Collection(SearchFieldDataType.Complex)) - { - Fields = - { - new SearchField(nameof(InnerModelWithIgnoredProperties.OtherField), SearchFieldDataType.Int32) { IsFilterable = true }, - } - } -#endif }; IList actualFields = BuildForType(typeof(ModelWithIgnoredProperties)); @@ -474,11 +448,7 @@ from type in modelTypes from tuple in testData select (type, tuple.dataType, tuple.fieldName); -#if EXPERIMENTAL_FIELDBUILDER private static IList BuildForType(Type modelType) => new FieldBuilder().Build(modelType); -#else - private static IList BuildForType(Type modelType) => FieldBuilder.BuildForType(modelType); -#endif private enum Direction { @@ -547,11 +517,7 @@ private class ModelWithEnum [KeyField] public string ID { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] -#else - [IsFilterable, IsSearchable, IsSortable, IsFacetable] -#endif public Direction Direction { get; set; } } @@ -560,11 +526,7 @@ private class ModelWithUnsupportedPrimitiveType [KeyField] public string ID { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public decimal Price { get; set; } } @@ -573,11 +535,7 @@ private class ModelWithUnsupportedEnumerableType [KeyField] public string ID { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public IEnumerable Buffer { get; set; } } @@ -586,11 +544,7 @@ private class ModelWithUnsupportedCollectionType [KeyField] public string ID { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public ICollection Buffer { get; set; } } @@ -599,11 +553,7 @@ private class InnerModelWithKey [KeyField] public string InnerID { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public int OtherField { get; set; } } @@ -617,11 +567,7 @@ private class ModelWithNestedKey private class InnerModelWithIgnoredProperties { -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public int OtherField { get; set; } [JsonIgnore] diff --git a/sdk/search/Azure.Search.Documents/tests/Models/LexicalAnalyzerNameTests.cs b/sdk/search/Azure.Search.Documents/tests/Models/LexicalAnalyzerNameTests.cs index fdb2c368789b6..7ca0c6c443d07 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/LexicalAnalyzerNameTests.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/LexicalAnalyzerNameTests.cs @@ -10,7 +10,6 @@ namespace Azure.Search.Documents.Tests.Models { public class LexicalAnalyzerNameTests { -#if EXPERIMENTAL_FIELDBUILDER [Test] public void PropertiesEqualConstantFields() { @@ -27,6 +26,5 @@ public void PropertiesEqualConstantFields() // Note: tested that declaring an extra property or field does fail the assert. CollectionAssert.AreEquivalent(properties, fields); } -#endif } } diff --git a/sdk/search/Azure.Search.Documents/tests/Models/RecursiveModel.cs b/sdk/search/Azure.Search.Documents/tests/Models/RecursiveModel.cs index 65473f5a7c54f..66e386fb58911 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/RecursiveModel.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/RecursiveModel.cs @@ -6,19 +6,12 @@ // TODO: Remove when https://github.com/Azure/azure-sdk-for-net/issues/11166 is completed. using Azure.Search.Documents.Indexes; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif namespace Azure.Search.Documents.Tests { public class RecursiveModel { -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public int Data { get; set; } // This is to test that FieldBuilder gracefully fails on recursive models. @@ -27,11 +20,7 @@ public class RecursiveModel public class OtherRecursiveModel { -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true, IsFacetable = true)] -#else - [IsFilterable, IsFacetable] -#endif public double Data { get; set; } public RecursiveModel RecursiveReference { get; set; } diff --git a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableCamelCaseModel.cs b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableCamelCaseModel.cs index 14456d6be71f5..3a698de3c2e0a 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableCamelCaseModel.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableCamelCaseModel.cs @@ -2,9 +2,6 @@ // Licensed under the MIT License. using System.Text.Json.Serialization; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif using KeyFieldAttribute = System.ComponentModel.DataAnnotations.KeyAttribute; #pragma warning disable SA1402 // File may only contain a single type @@ -13,18 +10,12 @@ // TODO: Remove when https://github.com/Azure/azure-sdk-for-net/issues/11166 is completed. namespace Azure.Search.Documents.Tests { -#if !EXPERIMENTAL_FIELDBUILDER - [SerializePropertyNamesAsCamelCase] -#endif public class ReflectableInnerCamelCaseModel { [JsonPropertyName("name")] public string Name { get; set; } } -#if !EXPERIMENTAL_FIELDBUILDER - [SerializePropertyNamesAsCamelCase] -#endif public class ReflectableCamelCaseModel { [KeyField] diff --git a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableModel.cs b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableModel.cs index 01c607037f858..61dfee3ac7e41 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableModel.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableModel.cs @@ -6,9 +6,6 @@ using System.Text.Json.Serialization; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; #else @@ -24,40 +21,22 @@ namespace Azure.Search.Documents.Tests { public class ReflectableAddress { -#if EXPERIMENTAL_FIELDBUILDER [SearchableField] -#else - [IsSearchable] -#endif public string City { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true, IsFacetable = true)] -#else - [IsFilterable, IsFacetable] -#endif public string Country { get; set; } } public class ReflectableComplexObject { -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnMicrosoft)] -#else - [IsSearchable] - [Analyzer("en.microsoft")] -#endif public string Name { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public int Rating { get; set; } // Ensure that leaf-field-specific attributes are ignored by FieldBuilder on complex fields. -#if EXPERIMENTAL_FIELDBUILDER [SearchableField( IsFilterable = true, IsSortable = true, @@ -67,17 +46,6 @@ public class ReflectableComplexObject SearchAnalyzerName = LexicalAnalyzerName.Values.ZhHantLucene, IndexAnalyzerName = LexicalAnalyzerName.Values.ZhHantLucene, SynonymMapNames = new[] { "myMap" })] -#else - [IsSearchable] - [IsFilterable] - [IsSortable] - [IsFacetable] - [IsRetrievable(false)] - [Analyzer("zh-Hant.lucene")] - [IndexAnalyzer("zh-Hant.lucene")] - [SearchAnalyzer("zh-Hant.lucene")] - [SynonymMaps("myMap")] -#endif public ReflectableAddress Address { get; set; } } @@ -96,80 +64,36 @@ public class ReflectableModel public DateTime TimeWithoutOffset { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(SynonymMapNames = new[] { "myMap" })] -#else - [IsSearchable] - [SynonymMaps("myMap")] -#endif public string Text { get; set; } public string UnsearchableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField] -#else - [IsSearchable] -#endif public string MoreText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public string FilterableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsSortable = true)] -#else - [IsSortable] -#endif public string SortableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFacetable = true)] -#else - [IsFacetable] -#endif public string FacetableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = true)] -#else - [IsRetrievable(false)] -#endif public string IrretrievableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = false)] -#else - [IsRetrievable(true)] -#endif public string ExplicitlyRetrievableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnMicrosoft)] -#else - [IsSearchable] - [Analyzer("en.microsoft")] -#endif public string TextWithAnalyzer { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(SearchAnalyzerName = LexicalAnalyzerName.Values.EsLucene)] -#else - [IsSearchable] - [SearchAnalyzer("es.lucene")] -#endif public string TextWithSearchAnalyzer { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(IndexAnalyzerName = LexicalAnalyzerName.Values.Whitespace)] -#else - [IsSearchable] - [IndexAnalyzer("whitespace")] -#endif public string TextWithIndexAnalyzer { get; set; } public string[] StringArray { get; set; } @@ -285,11 +209,7 @@ public class ReflectableModel public ICollection ComplexICollection { get; set; } [JsonIgnore] -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = true)] -#else - [IsRetrievable(false)] -#endif #pragma warning disable IDE1006 // Naming Styles public RecordEnum recordEnum { get; set; } #pragma warning restore IDE1006 // Naming Styles diff --git a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructCamelCaseModel.cs b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructCamelCaseModel.cs index f15b9ea23436c..2681f11039ea3 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructCamelCaseModel.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructCamelCaseModel.cs @@ -2,9 +2,6 @@ // Licensed under the MIT License. using System.Text.Json.Serialization; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif using KeyFieldAttribute = System.ComponentModel.DataAnnotations.KeyAttribute; #pragma warning disable SA1402 // File may only contain a single type @@ -13,18 +10,12 @@ // TODO: Remove when https://github.com/Azure/azure-sdk-for-net/issues/11166 is completed. namespace Azure.Search.Documents.Tests { -#if !EXPERIMENTAL_FIELDBUILDER - [SerializePropertyNamesAsCamelCase] -#endif public struct ReflectableInnerStructCamelCaseModel { [JsonPropertyName("name")] public string Name { get; set; } } -#if !EXPERIMENTAL_FIELDBUILDER - [SerializePropertyNamesAsCamelCase] -#endif public struct ReflectableStructCamelCaseModel { [KeyField] diff --git a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructModel.cs b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructModel.cs index 8655a831c339e..252f69cd1f6e2 100644 --- a/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructModel.cs +++ b/sdk/search/Azure.Search.Documents/tests/Models/ReflectableStructModel.cs @@ -6,9 +6,6 @@ using System.Text.Json.Serialization; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; -#if !EXPERIMENTAL_FIELDBUILDER -using Azure.Search.Documents.Samples; -#endif #if EXPERIMENTAL_SPATIAL using Azure.Core.Spatial; #else @@ -24,40 +21,22 @@ namespace Azure.Search.Documents.Tests { public struct ReflectableAddressStruct { -#if EXPERIMENTAL_FIELDBUILDER [SearchableField] -#else - [IsSearchable] -#endif public string City { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true, IsFacetable = true)] -#else - [IsFilterable, IsFacetable] -#endif public string Country { get; set; } } public struct ReflectableComplexStruct { -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnMicrosoft)] -#else - [IsSearchable] - [Analyzer("en.microsoft")] -#endif public string Name { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public int Rating { get; set; } // Ensure that leaf-field-specific attributes are ignored by FieldBuilder on complex fields. -#if EXPERIMENTAL_FIELDBUILDER [SearchableField( IsFilterable = true, IsSortable = true, @@ -67,17 +46,6 @@ public struct ReflectableComplexStruct SearchAnalyzerName = LexicalAnalyzerName.Values.ZhHantLucene, IndexAnalyzerName = LexicalAnalyzerName.Values.ZhHantLucene, SynonymMapNames = new[] { "myMap" })] -#else - [IsSearchable] - [IsFilterable] - [IsSortable] - [IsFacetable] - [IsRetrievable(false)] - [Analyzer("zh-Hant.lucene")] - [IndexAnalyzer("zh-Hant.lucene")] - [SearchAnalyzer("zh-Hant.lucene")] - [SynonymMaps("myMap")] -#endif public ReflectableAddressStruct Address { get; set; } } @@ -96,80 +64,36 @@ public struct ReflectableStructModel public DateTime TimeWithoutOffset { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(SynonymMapNames = new[] { "myMap" })] -#else - [IsSearchable] - [SynonymMaps("myMap")] -#endif public string Text { get; set; } public string UnsearchableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField] -#else - [IsSearchable] -#endif public string MoreText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFilterable = true)] -#else - [IsFilterable] -#endif public string FilterableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsSortable = true)] -#else - [IsSortable] -#endif public string SortableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsFacetable = true)] -#else - [IsFacetable] -#endif public string FacetableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = true)] -#else - [IsRetrievable(false)] -#endif public string IrretrievableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = false)] -#else - [IsRetrievable(true)] -#endif public string ExplicitlyRetrievableText { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnMicrosoft)] -#else - [IsSearchable] - [Analyzer("en.microsoft")] -#endif public string TextWithAnalyzer { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(SearchAnalyzerName = LexicalAnalyzerName.Values.EsLucene)] -#else - [IsSearchable] - [SearchAnalyzer("es.lucene")] -#endif public string TextWithSearchAnalyzer { get; set; } -#if EXPERIMENTAL_FIELDBUILDER [SearchableField(IndexAnalyzerName = LexicalAnalyzerName.Values.Whitespace)] -#else - [IsSearchable] - [IndexAnalyzer("whitespace")] -#endif public string TextWithIndexAnalyzer { get; set; } public string[] StringArray { get; set; } @@ -285,11 +209,7 @@ public struct ReflectableStructModel public ICollection ComplexICollection { get; set; } [JsonIgnore] -#if EXPERIMENTAL_FIELDBUILDER [SimpleField(IsHidden = true)] -#else - [IsRetrievable(false)] -#endif #pragma warning disable IDE1006 // Naming Styles public RecordEnum recordEnum { get; set; } #pragma warning restore IDE1006 // Naming Styles diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/AnalyzerAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/AnalyzerAttribute.cs deleted file mode 100644 index 7524dc27b6540..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/AnalyzerAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the generated by for - /// the target property should have its property set to the - /// specified analyzer. - /// - [AttributeUsage(AttributeTargets.Property)] - public class AnalyzerAttribute : Attribute - { - /// - /// Indicates that the specified analyzer should be used. - /// - /// - /// The name of the analyzer. Use one of the names on - /// or the name of a custom analyzer. - /// - public AnalyzerAttribute(string analyzerName) - { - Name = analyzerName; - } - - /// - /// The name of the analyzer. - /// - public string Name { get; } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilder.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilder.cs deleted file mode 100644 index 9d825e0c9f9b4..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilder.cs +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; -using Azure.Search.Documents.Indexes.Models; -#if EXPERIMENTAL_SPATIAL -using Azure.Core.Spatial; -#else -using Microsoft.Spatial; -#endif - -namespace Azure.Search.Documents.Samples -{ - /// - /// Builds field definitions for a search index by reflecting over a user-defined model type. - /// - /// - /// - /// This was ported from the Microsoft.Azure.Search.Service package - /// to make migrating from using Microsoft.Azure.Search to Azure.Search.Documents easier. - /// It also uses System.Text.Json instead of Newtonsoft.Json (JSON.NET). - /// - /// - /// This is only a sample you can include in your code and future implementations may change - /// to follow modern guidelines and design principles. - /// - /// - public static class FieldBuilder - { - private static readonly IReadOnlyDictionary s_primitiveTypeMap = - new ReadOnlyDictionary( - new Dictionary() - { - [typeof(string)] = SearchFieldDataType.String, - [typeof(int)] = SearchFieldDataType.Int32, - [typeof(long)] = SearchFieldDataType.Int64, - [typeof(double)] = SearchFieldDataType.Double, - [typeof(bool)] = SearchFieldDataType.Boolean, - [typeof(DateTime)] = SearchFieldDataType.DateTimeOffset, - [typeof(DateTimeOffset)] = SearchFieldDataType.DateTimeOffset, -#if EXPERIMENTAL_SPATIAL - [typeof(PointGeometry)] = SearchFieldDataType.GeographyPoint, -#else - [typeof(GeographyPoint)] = SearchFieldDataType.GeographyPoint, -#endif - }); - - private static readonly ISet s_unsupportedTypes = - new HashSet - { - typeof(decimal), - }; - - private static JsonNamingPolicy CamelCaseResolver { get; } = JsonNamingPolicy.CamelCase; - - private static JsonNamingPolicy DefaultResolver { get; } = DefaultJsonNamingPolicy.Shared; - - /// - /// Creates a collection of objects corresponding to - /// the properties of the type supplied. - /// - /// - /// The type for which fields will be created, based on its properties. - /// - /// A collection of fields. - public static IList BuildForType() => BuildForType(typeof(T)); - - /// - /// Creates a collection of objects corresponding to - /// the properties of the type supplied. - /// - /// - /// The type for which fields will be created, based on its properties. - /// - /// A collection of fields. - public static IList BuildForType(Type modelType) - { - bool useCamelCase = SerializePropertyNamesAsCamelCaseAttribute.IsDefinedOnType(modelType); - JsonNamingPolicy namingPolicy = useCamelCase - ? CamelCaseResolver - : DefaultResolver; - return BuildForType(modelType, namingPolicy); - } - - /// - /// Creates a collection of objects corresponding to - /// the properties of the type supplied. - /// - /// - /// The type for which fields will be created, based on its properties. - /// - /// - /// to use. - /// This ensures that the field names are generated in a way that is - /// consistent with the way the model will be serialized. - /// - /// A collection of fields. - public static IList BuildForType(JsonNamingPolicy namingPolicy) => BuildForType(typeof(T), namingPolicy); - - /// - /// Creates a collection of objects corresponding to - /// the properties of the type supplied. - /// - /// - /// The type for which fields will be created, based on its properties. - /// - /// - /// to use. - /// Contract resolver that the SearchIndexClient will use. - /// This ensures that the field names are generated in a way that is - /// consistent with the way the model will be serialized. - /// - /// A collection of fields. - /// or is null. - public static IList BuildForType(Type modelType, JsonNamingPolicy namingPolicy) - { - if (modelType is null) - { throw new ArgumentNullException(nameof(modelType)); - } - - if (namingPolicy is null) - { throw new ArgumentNullException(nameof(namingPolicy)); - } - - ArgumentException FailOnNonObjectDataType() - { - string errorMessage = - $"Type '{modelType}' does not have properties which map to fields of an Azure Search index. Please use a " + - "class or struct with public properties."; - - throw new ArgumentException(errorMessage, nameof(modelType)); - } - - if (ObjectInfo.TryGet(modelType, out ObjectInfo info)) - { - if (info.Properties.Length == 0) - { - throw FailOnNonObjectDataType(); - } - - // Use Stack to avoid a dependency on ImmutableStack for now. - return BuildForTypeRecursive(modelType, info, namingPolicy, new Stack(new[] { modelType })); - } - - throw FailOnNonObjectDataType(); - } - - private static IList BuildForTypeRecursive( - Type modelType, - ObjectInfo info, - JsonNamingPolicy namingPolicy, - Stack processedTypes) - { - SearchField BuildField(PropertyInfo prop) - { - static bool ShouldIgnore(Attribute attribute) => - attribute is JsonIgnoreAttribute || attribute is FieldBuilderIgnoreAttribute; - - IList attributes = prop.GetCustomAttributes(true).Cast().ToArray(); - if (attributes.Any(ShouldIgnore)) - { - return null; - } - - SearchField CreateComplexField(SearchFieldDataType dataType, Type underlyingClrType, ObjectInfo info) - { - if (processedTypes.Contains(underlyingClrType)) - { - // Skip recursive types. - return null; - } - - processedTypes.Push(underlyingClrType); - try - { - IList subFields = - BuildForTypeRecursive(underlyingClrType, info, namingPolicy, processedTypes); - - string fieldName = namingPolicy.ConvertName(prop.Name); - - SearchField field = new SearchField(fieldName, dataType); - foreach (SearchField subField in subFields) - { - field.Fields.Add(subField); - } - - return field; - } - finally - { - processedTypes.Pop(); - } - } - - SearchField CreateSimpleField(SearchFieldDataType SearchFieldDataType) - { - string fieldName = namingPolicy.ConvertName(prop.Name); - - SearchField field = new SearchField(fieldName, SearchFieldDataType); - foreach (Attribute attribute in attributes) - { - switch (attribute) - { - case IsSearchableAttribute _: - field.IsSearchable = true; - break; - - case IsFilterableAttribute _: - field.IsFilterable = true; - break; - - case IsSortableAttribute _: - field.IsSortable = true; - break; - - case IsFacetableAttribute _: - field.IsFacetable = true; - break; - - case IsRetrievableAttribute isRetrievableAttribute: - field.IsHidden = !isRetrievableAttribute.IsRetrievable; - break; - - case AnalyzerAttribute analyzerAttribute: - field.AnalyzerName = analyzerAttribute.Name; - break; - - case SearchAnalyzerAttribute searchAnalyzerAttribute: - field.SearchAnalyzerName = searchAnalyzerAttribute.Name; - break; - - case IndexAnalyzerAttribute indexAnalyzerAttribute: - field.IndexAnalyzerName = indexAnalyzerAttribute.Name; - break; - - case SynonymMapsAttribute synonymMapsAttribute: - foreach (string synonymMapName in synonymMapsAttribute.SynonymMaps) - { - field.SynonymMapNames.Add(synonymMapName); - } - break; - - default: - Type attributeType = attribute.GetType(); - - // Match on name to avoid dependency - don't want to force people not using - // this feature to bring in the annotations component. - // - // Also, ignore key attributes on sub-fields. - if (attributeType.FullName == "System.ComponentModel.DataAnnotations.KeyAttribute" && - processedTypes.Count <= 1) - { - field.IsKey = true; - } - break; - } - } - - return field; - } - - ArgumentException FailOnUnknownDataType() - { - string errorMessage = - $"Property '{prop.Name}' is of type '{prop.PropertyType}', which does not map to an " + - "Azure Search data type. Please use a supported data type or mark the property with [JsonIgnore] or " + - "[FieldBuilderIgnore] and define the field by creating a SearchField object."; - - return new ArgumentException(errorMessage, nameof(modelType)); - } - - IDataTypeInfo dataTypeInfo = GetDataTypeInfo(prop.PropertyType, namingPolicy); - - return dataTypeInfo.Match( - onUnknownDataType: () => throw FailOnUnknownDataType(), - onSimpleDataType: CreateSimpleField, - onComplexDataType: CreateComplexField); - } - - return info.Properties.Select(BuildField).Where(field => field != null).ToArray(); - } - - private static IDataTypeInfo GetDataTypeInfo(Type propertyType, JsonNamingPolicy namingPolicy) - { - static bool IsNullableType(Type type) => - type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); - - if (s_primitiveTypeMap.TryGetValue(propertyType, out SearchFieldDataType SearchFieldDataType)) - { - return DataTypeInfo.Simple(SearchFieldDataType); - } - else if (IsNullableType(propertyType)) - { - return GetDataTypeInfo(propertyType.GenericTypeArguments[0], namingPolicy); - } - else if (TryGetEnumerableElementType(propertyType, out Type elementType)) - { - IDataTypeInfo elementTypeInfo = GetDataTypeInfo(elementType, namingPolicy); - return DataTypeInfo.AsCollection(elementTypeInfo); - } - else if (ObjectInfo.TryGet(propertyType, out ObjectInfo info)) - { - return DataTypeInfo.Complex(SearchFieldDataType.Complex, propertyType, info); - } - else - { - return DataTypeInfo.Unknown; - } - } - - private static bool TryGetEnumerableElementType(Type candidateType, out Type elementType) - { - static Type GetElementTypeIfIEnumerable(Type t) => - t.IsConstructedGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>) - ? t.GenericTypeArguments[0] - : null; - - elementType = GetElementTypeIfIEnumerable(candidateType); - if (elementType != null) - { - return true; - } - else - { - TypeInfo ti = candidateType.GetTypeInfo(); - var listElementTypes = ti - .ImplementedInterfaces - .Select(GetElementTypeIfIEnumerable) - .Where(p => p != null) - .ToList(); - - if (listElementTypes.Count == 1) - { - elementType = listElementTypes[0]; - return true; - } - else - { - return false; - } - } - } - - private interface IDataTypeInfo - { - T Match( - Func onUnknownDataType, - Func onSimpleDataType, - Func onComplexDataType); - } - - private static class DataTypeInfo - { - public static IDataTypeInfo Unknown { get; } = new UnknownDataTypeInfo(); - - public static IDataTypeInfo Simple(SearchFieldDataType SearchFieldDataType) => new SimpleDataTypeInfo(SearchFieldDataType); - - public static IDataTypeInfo Complex(SearchFieldDataType SearchFieldDataType, Type underlyingClrType, ObjectInfo info) => - new ComplexDataTypeInfo(SearchFieldDataType, underlyingClrType, info); - - public static IDataTypeInfo AsCollection(IDataTypeInfo dataTypeInfo) => - dataTypeInfo.Match( - onUnknownDataType: () => Unknown, - onSimpleDataType: SearchFieldDataType => Simple(SearchFieldDataType.Collection(SearchFieldDataType)), - onComplexDataType: (SearchFieldDataType, underlyingClrType, info) => - Complex(SearchFieldDataType.Collection(SearchFieldDataType), underlyingClrType, info)); - - private sealed class UnknownDataTypeInfo : IDataTypeInfo - { - public UnknownDataTypeInfo() - { - } - - public T Match( - Func onUnknownDataType, - Func onSimpleDataType, - Func onComplexDataType) - => onUnknownDataType(); - } - - private sealed class SimpleDataTypeInfo : IDataTypeInfo - { - private readonly SearchFieldDataType _dataType; - - public SimpleDataTypeInfo(SearchFieldDataType SearchFieldDataType) - { - _dataType = SearchFieldDataType; - } - - public T Match( - Func onUnknownDataType, - Func onSimpleDataType, - Func onComplexDataType) - => onSimpleDataType(_dataType); - } - - private sealed class ComplexDataTypeInfo : IDataTypeInfo - { - private readonly SearchFieldDataType _dataType; - private readonly Type _underlyingClrType; - private readonly ObjectInfo _info; - - public ComplexDataTypeInfo(SearchFieldDataType SearchFieldDataType, Type underlyingClrType, ObjectInfo info) - { - _dataType = SearchFieldDataType; - _underlyingClrType = underlyingClrType; - _info = info; - } - - public T Match( - Func onUnknownDataType, - Func onSimpleDataType, - Func onComplexDataType) - => onComplexDataType(_dataType, _underlyingClrType, _info); - } - } - - private class ObjectInfo - { - private ObjectInfo(Type type) - { - Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); - } - - public static bool TryGet(Type type, out ObjectInfo info) - { - // Close approximation to Newtonsoft.Json.Serialization.DefaultContractResolver. - if (!type.IsPrimitive && !type.IsEnum && !s_unsupportedTypes.Contains(type) && !s_primitiveTypeMap.ContainsKey(type) && !typeof(IEnumerable).IsAssignableFrom(type)) - { - info = new ObjectInfo(type); - return true; - } - - info = null; - return false; - } - - public PropertyInfo[] Properties { get; } - } - - private class DefaultJsonNamingPolicy : JsonNamingPolicy - { - public static JsonNamingPolicy Shared { get; } = new DefaultJsonNamingPolicy(); - - public override string ConvertName(string name) => name; - } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilderIgnoreAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilderIgnoreAttribute.cs deleted file mode 100644 index bc0316d940761..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/FieldBuilderIgnoreAttribute.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Text.Json.Serialization; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the target property should be ignored by . - /// - /// - /// This attribute is useful in situations where a property definition doesn't cleanly map to a - /// object, but its values still need to be converted to and from JSON. In that case, - /// can't be used since it would disable JSON conversion. - /// An example of a scenario where this is useful is when mapping between a string field in Azure Cognitive Search and an enum - /// property. - /// - [AttributeUsage(AttributeTargets.Property)] - public class FieldBuilderIgnoreAttribute : Attribute - { - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IndexAnalyzerAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IndexAnalyzerAttribute.cs deleted file mode 100644 index 422efc39b0a29..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IndexAnalyzerAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the generated by for - /// the target property should have its property set to the - /// specified analyzer. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IndexAnalyzerAttribute : Attribute - { - /// - /// Indicates that the specified analyzer should be used. - /// - /// - /// The name of the analyzer. Use one of the names on - /// or the name of a custom analyzer. - /// - public IndexAnalyzerAttribute(string analyzerName) - { - Name = analyzerName; - } - - /// - /// The name of the analyzer. - /// - public string Name { get; } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFacetableAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFacetableAttribute.cs deleted file mode 100644 index fc90d369b511f..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFacetableAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Azure.Search.Documents.Samples -{ - - /// - /// Indicates that it is possible to facet on this field. Not valid for - /// geo-point fields. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IsFacetableAttribute : Attribute - { - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFilterableAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFilterableAttribute.cs deleted file mode 100644 index f644fb92d759f..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsFilterableAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the field can be used in filter expressions. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IsFilterableAttribute : Attribute - { - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsRetrievableAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsRetrievableAttribute.cs deleted file mode 100644 index 9d74c75e89572..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsRetrievableAttribute.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates whether the field can be returned in a search result. This - /// defaults to true, so this attribute only has any effect if you use it - /// as [IsRetrievable(false)]. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IsRetrievableAttribute : Attribute - { - /// - /// Indicates that the specified value should be used to negate the - /// flag of the target field. - /// - /// true if the target field should be included in - /// search results, false otherwise. - public IsRetrievableAttribute(bool isRetrievable) - { - IsRetrievable = isRetrievable; - } - - /// - /// true if the target field should be included in search results, false otherwise. - /// - public bool IsRetrievable { get; } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSearchableAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSearchableAttribute.cs deleted file mode 100644 index c181db244d520..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSearchableAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Causes the field to be included in full-text searches. Valid only for - /// string or string collection fields. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IsSearchableAttribute : Attribute - { - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSortableAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSortableAttribute.cs deleted file mode 100644 index acba89259cb4b..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/IsSortableAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the field can be used in orderby expressions. Not valid - /// for string collection fields. - /// - [AttributeUsage(AttributeTargets.Property)] - public class IsSortableAttribute : Attribute - { - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SearchAnalyzerAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SearchAnalyzerAttribute.cs deleted file mode 100644 index 0a33a3d0a9a88..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SearchAnalyzerAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the generated by for - /// the target property should have its property set to the - /// specified analyzer. - /// - [AttributeUsage(AttributeTargets.Property)] - public class SearchAnalyzerAttribute : Attribute - { - /// - /// Indicates that the specified analyzer should be used. - /// - /// - /// The name of the analyzer. Use one of the names on - /// or the name of a custom analyzer. - /// - public SearchAnalyzerAttribute(string analyzerName) - { - Name = analyzerName; - } - - /// - /// The name of the analyzer. - /// - public string Name { get; } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SerializePropertyNamesAsCamelCaseAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SerializePropertyNamesAsCamelCaseAttribute.cs deleted file mode 100644 index b296197cddff9..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SerializePropertyNamesAsCamelCaseAttribute.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Linq; -using System.Reflection; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the public properties of a model type should be serialized as camel-case in order to match - /// the field names of a search index. - /// - /// - /// Types without this attribute are expected to have property names that exactly match their corresponding - /// fields names in Azure Cognitive Search. Otherwise, it would not be possible to use instances of the type to populate - /// the index. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] - public class SerializePropertyNamesAsCamelCaseAttribute : Attribute - { - /// - /// Indicates whether the given type is annotated with SerializePropertyNamesAsCamelCaseAttribute. - /// - /// The type to test. - /// true if the given type is annotated with SerializePropertyNamesAsCamelCaseAttribute, - /// false otherwise. - public static bool IsDefinedOnType() => IsDefinedOnType(typeof(T)); - - /// - /// Indicates whether the given type is annotated with SerializePropertyNamesAsCamelCaseAttribute. - /// - /// The type to test. - /// true if the given type is annotated with SerializePropertyNamesAsCamelCaseAttribute, - /// false otherwise. - public static bool IsDefinedOnType(Type modelType) => - modelType - .GetTypeInfo() - .GetCustomAttributes(typeof(SerializePropertyNamesAsCamelCaseAttribute), inherit: true) - .Any(); - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SynonymMapsAttribute.cs b/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SynonymMapsAttribute.cs deleted file mode 100644 index 428fb380ebafd..0000000000000 --- a/sdk/search/Azure.Search.Documents/tests/Samples/FieldBuilder/SynonymMapsAttribute.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using Azure.Search.Documents.Indexes.Models; - -namespace Azure.Search.Documents.Samples -{ - /// - /// Indicates that the generated by for - /// the target property should have its property set to the - /// specified value. - /// - [AttributeUsage(AttributeTargets.Property)] - public class SynonymMapsAttribute : Attribute - { - /// - /// Indicates that the specified synonym maps should be used for searches on the target field. - /// - /// A list of synonym map names that associates synonym maps with the field. - /// This option can be used only with searchable fields. Currently only one synonym map per field is - /// supported. Assigning a synonym map to a field ensures that query terms targeting that field are - /// expanded at query-time using the rules in the synonym map. - /// - public SynonymMapsAttribute(params string[] synonymMaps) - { - SynonymMaps = synonymMaps; - } - - /// - /// A list of synonym map names that associates synonym maps with the field. - /// - public IList SynonymMaps { get; } - } -} diff --git a/sdk/search/Azure.Search.Documents/tests/Samples/Readme.cs b/sdk/search/Azure.Search.Documents/tests/Samples/Readme.cs index abdd668688979..a8dcf98fd58ad 100644 --- a/sdk/search/Azure.Search.Documents/tests/Samples/Readme.cs +++ b/sdk/search/Azure.Search.Documents/tests/Samples/Readme.cs @@ -192,7 +192,6 @@ public async Task Options() #endregion Snippet:Azure_Search_Tests_Samples_Readme_Options } -#if EXPERIMENTAL_FIELDBUILDER // This won't condition the README.md file, which will require manual effort. [Test] [SyncOnly] public async Task CreateIndex() @@ -229,7 +228,6 @@ public async Task CreateIndex() resources.IndexName = index.Name; } -#endif [Test] [SyncOnly]