Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of FieldBuilder #14023

Merged
merged 15 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sdk/search/Azure.Search.Documents/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## 11.1.0-preview.1 (Unreleased)

### Added

- Added `SearchClientOptions.Serializer` to set which `ObjectSerializer` to use for serialization.
- Added `FieldBuilder` to easily create `SearchIndex` fields from a model type.

### Removed

- Removed `$select` from the query parameters logged by default. You can add it back via `SearchClientOptions.Diagnostics.LoggedQueryParameters("$select");` if desired.
Expand Down
20 changes: 15 additions & 5 deletions sdk/search/Azure.Search.Documents/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@

<!-- Azure.Core.Experimental feature flags -->
<PropertyGroup>
<!-- Enable everything by default -->
<!-- Disable everything by default -->
<UseAzureCoreExperimental Condition="'$(UseAzureCoreExperimental)' == ''">false</UseAzureCoreExperimental>

<!-- Use Azure.Core.Experimental's Spatial features -->
<!-- (Note: a number of tests will need re-recording if you disable) -->
<UseAzureCoreExperimentalSpatial Condition="'$(UseAzureCoreExperimentalSpatial)' == ''">$(UseAzureCoreExperimental)</UseAzureCoreExperimentalSpatial>
<DefineConstants Condition="'$(UseAzureCoreExperimentalSpatial)' == 'true'">EXPERIMENTAL_SPATIAL;$(DefineConstants)</DefineConstants>

<!-- Use Azure.Core.Experimental's ObjectSerializer features -->
<UseAzureCoreExperimentalSerializer Condition="'$(UseAzureCoreExperimentalSerializer)' == ''">$(UseAzureCoreExperimental)</UseAzureCoreExperimentalSerializer>
<DefineConstants Condition="'$(UseAzureCoreExperimentalSerializer)' == 'true'">EXPERIMENTAL_SERIALIZER;$(DefineConstants)</DefineConstants>
<!-- Use Azure.Core's ObjectSerializer features -->
<UseAzureCoreSerializer Condition="'$(UseAzureCoreSerializer)' == ''">true</UseAzureCoreSerializer>
<DefineConstants Condition="'$(UseAzureCoreSerializer)' == 'true'">EXPERIMENTAL_SERIALIZER;$(DefineConstants)</DefineConstants>
heaths marked this conversation as resolved.
Show resolved Hide resolved

<!-- Use Azure.Core.Experimental's DynamicData features (stubbed out in Search for now) -->
<UseAzureCoreExperimentalDynamic Condition="'$(UseAzureCoreExperimentalDynamic)' == ''">$(UseAzureCoreExperimental)</UseAzureCoreExperimentalDynamic>
<DefineConstants Condition="'$(UseAzureCoreExperimentalDynamic)' == 'true'">EXPERIMENTAL_DYNAMIC;$(DefineConstants)</DefineConstants>

<UseFieldBuilder Condition="'$(UseFieldBuilder)' == '' AND '$(UseAzureCoreSerializer)' == 'true'">true</UseFieldBuilder>
<DefineConstants Condition="'$(UseFieldBuilder)' == 'true'">EXPERIMENTAL_FIELDBUILDER;$(DefineConstants)</DefineConstants>

<!-- Use a Package or Project reference to Azure.Core.Experimental -->
<AddExperimentalReference Condition="('$(UseAzureCoreExperimentalSpatial)' == 'true') OR ('$(UseAzureCoreExperimentalSerializer)' == 'true') OR ('$(UseAzureCoreExperimentalSerializer)' == 'true')">true</AddExperimentalReference>
<AddExperimentalReference Condition="('$(UseAzureCoreExperimentalSpatial)' == 'true') OR ('$(UseAzureCoreExperimentalDynamic)' == 'true')">true</AddExperimentalReference>
<UseExperimentalProjectReference Condition="'$(UseExperimentalProjectReference)' == ''">$(UseProjectReferenceToAzureClients)</UseExperimentalProjectReference>
</PropertyGroup>

Expand All @@ -33,6 +36,13 @@
Include="Azure.Core.Experimental" />
</ItemGroup>

<!-- Other package references -->
<ItemGroup>
<PackageReference
Condition="'$(UseAzureCoreExperimentalSpatial)' != 'true'"
Include="Microsoft.Spatial" />
heaths marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

<!--
Add any shared properties you want for the projects under this package directory that need to be set before the auto imported Directory.Build.props
-->
Expand Down
51 changes: 38 additions & 13 deletions sdk/search/Azure.Search.Documents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,20 @@ Let's explore them with a search for a "luxury" hotel.
We can decorate our own C# types with [attributes from `System.Text.Json`](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-how-to):

```C# Snippet:Azure_Search_Tests_Samples_Readme_StaticType
public class Hotel
{
[JsonPropertyName("hotelId")]
public string Id { get; set; }

[JsonPropertyName("hotelName")]
public string Name { get; set; }
}
public class Hotel
{
[JsonPropertyName("hotelId")]
#if EXPERIMENTAL_FIELDBUILDER
heaths marked this conversation as resolved.
Show resolved Hide resolved
[SimpleField(IsKey = true, IsFilterable = true, IsSortable = true)]
#endif
public string Id { get; set; }

[JsonPropertyName("hotelName")]
#if EXPERIMENTAL_FIELDBUILDER
[SearchableField(IsFilterable = true, IsSortable = true)]
#endif
public string Name { get; set; }
}
```

Then we use them as the type parameter when querying to return strongly-typed search results:
Expand Down Expand Up @@ -276,8 +282,8 @@ SearchResults<Hotel> response = client.Search<Hotel>("luxury", options);
### Creating an index

You can use the `SearchIndexClient` to create a search index. Fields can be
defined using convenient `SimpleField`, `SearchableField`, or `ComplexField`
classes. Indexes can also define suggesters, lexical analyzers, and more.
defined from a model class using `FieldBuilder`. Indexes can also define
suggesters, lexical analyzers, and more:

```C# Snippet:Azure_Search_Tests_Samples_Readme_CreateIndex
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
Expand All @@ -287,7 +293,26 @@ string key = Environment.GetEnvironmentVariable("SEARCH_API_KEY");
AzureKeyCredential credential = new AzureKeyCredential(key);
SearchIndexClient client = new SearchIndexClient(endpoint, credential);

// Create the index
// Create the index using FieldBuilder.
SearchIndex index = new SearchIndex("hotels")
{
Fields = new FieldBuilder().Build(typeof(Hotel)),
Suggesters =
{
// Suggest query terms from the hotelName field.
new SearchSuggester("sg", "hotelName")
}
};

client.CreateIndex(index);
```

In scenarios when the model is not known or cannot be modified, you can
also create fields explicitly using convenient `SimpleField`,
`SearchableField`, or `ComplexField` classes:

```C# Snippet:Azure_Search_Tests_Samples_Readme_CreateManualIndex
// Create the index using field definitions.
SearchIndex index = new SearchIndex("hotels")
{
Fields =
Expand All @@ -310,8 +335,8 @@ SearchIndex index = new SearchIndex("hotels")
},
Suggesters =
{
// Suggest query terms from both the hotelName and description fields.
new SearchSuggester("sg", "hotelName", "description")
// Suggest query terms from the hotelName field.
new SearchSuggester("sg", "hotelName")
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public SearchClient(System.Uri endpoint, string indexName, Azure.AzureKeyCredent
public partial class SearchClientOptions : Azure.Core.ClientOptions
{
public SearchClientOptions(Azure.Search.Documents.SearchClientOptions.ServiceVersion version = Azure.Search.Documents.SearchClientOptions.ServiceVersion.V2020_06_30) { }
public Azure.Core.Serialization.ObjectSerializer Serializer { get { throw null; } set { } }
public Azure.Search.Documents.SearchClientOptions.ServiceVersion Version { get { throw null; } }
public enum ServiceVersion
{
Expand Down Expand Up @@ -103,6 +104,26 @@ public SuggestOptions() { }
}
namespace Azure.Search.Documents.Indexes
{
public partial class FieldBuilder
{
public FieldBuilder() { }
public Azure.Core.Serialization.ObjectSerializer Serializer { get { throw null; } set { } }
public System.Collections.Generic.IList<Azure.Search.Documents.Indexes.Models.SearchField> Build(System.Type modelType) { throw null; }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public partial class FieldBuilderIgnoreAttribute : System.Attribute
{
public FieldBuilderIgnoreAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public partial class SearchableFieldAttribute : Azure.Search.Documents.Indexes.SimpleFieldAttribute
{
public SearchableFieldAttribute() { }
public string AnalyzerName { get { throw null; } set { } }
public string IndexAnalyzerName { get { throw null; } set { } }
public string SearchAnalyzerName { get { throw null; } set { } }
public string[] SynonymMapNames { get { throw null; } set { } }
}
public partial class SearchIndexClient
{
protected SearchIndexClient() { }
Expand Down Expand Up @@ -202,6 +223,16 @@ public SearchIndexerClient(System.Uri endpoint, Azure.AzureKeyCredential credent
public virtual Azure.Response RunIndexer(string indexerName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response> RunIndexerAsync(string indexerName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public partial class SimpleFieldAttribute : System.Attribute
{
public SimpleFieldAttribute() { }
public bool IsFacetable { get { throw null; } set { } }
public bool IsFilterable { get { throw null; } set { } }
public bool IsHidden { get { throw null; } set { } }
public bool IsKey { get { throw null; } set { } }
public bool IsSortable { get { throw null; } set { } }
}
}
namespace Azure.Search.Documents.Indexes.Models
{
Expand Down Expand Up @@ -729,6 +760,102 @@ internal LexicalAnalyzer() { }
public static implicit operator Azure.Search.Documents.Indexes.Models.LexicalAnalyzerName (string value) { throw null; }
public static bool operator !=(Azure.Search.Documents.Indexes.Models.LexicalAnalyzerName left, Azure.Search.Documents.Indexes.Models.LexicalAnalyzerName right) { throw null; }
public override string ToString() { throw null; }
public static partial class Values
{
public const string ArLucene = "ar.lucene";
public const string ArMicrosoft = "ar.microsoft";
public const string BgLucene = "bg.lucene";
public const string BgMicrosoft = "bg.microsoft";
public const string BnMicrosoft = "bn.microsoft";
public const string CaLucene = "ca.lucene";
public const string CaMicrosoft = "ca.microsoft";
public const string CsLucene = "cs.lucene";
public const string CsMicrosoft = "cs.microsoft";
public const string DaLucene = "da.lucene";
public const string DaMicrosoft = "da.microsoft";
public const string DeLucene = "de.lucene";
public const string DeMicrosoft = "de.microsoft";
public const string ElLucene = "el.lucene";
public const string ElMicrosoft = "el.microsoft";
public const string EnLucene = "en.lucene";
public const string EnMicrosoft = "en.microsoft";
public const string EsLucene = "es.lucene";
public const string EsMicrosoft = "es.microsoft";
public const string EtMicrosoft = "et.microsoft";
public const string EuLucene = "eu.lucene";
public const string FaLucene = "fa.lucene";
public const string FiLucene = "fi.lucene";
public const string FiMicrosoft = "fi.microsoft";
public const string FrLucene = "fr.lucene";
public const string FrMicrosoft = "fr.microsoft";
public const string GaLucene = "ga.lucene";
public const string GlLucene = "gl.lucene";
public const string GuMicrosoft = "gu.microsoft";
public const string HeMicrosoft = "he.microsoft";
public const string HiLucene = "hi.lucene";
public const string HiMicrosoft = "hi.microsoft";
public const string HrMicrosoft = "hr.microsoft";
public const string HuLucene = "hu.lucene";
public const string HuMicrosoft = "hu.microsoft";
public const string HyLucene = "hy.lucene";
public const string IdLucene = "id.lucene";
public const string IdMicrosoft = "id.microsoft";
public const string IsMicrosoft = "is.microsoft";
public const string ItLucene = "it.lucene";
public const string ItMicrosoft = "it.microsoft";
public const string JaLucene = "ja.lucene";
public const string JaMicrosoft = "ja.microsoft";
public const string Keyword = "keyword";
public const string KnMicrosoft = "kn.microsoft";
public const string KoLucene = "ko.lucene";
public const string KoMicrosoft = "ko.microsoft";
public const string LtMicrosoft = "lt.microsoft";
public const string LvLucene = "lv.lucene";
public const string LvMicrosoft = "lv.microsoft";
public const string MlMicrosoft = "ml.microsoft";
public const string MrMicrosoft = "mr.microsoft";
public const string MsMicrosoft = "ms.microsoft";
public const string NbMicrosoft = "nb.microsoft";
public const string NlLucene = "nl.lucene";
public const string NlMicrosoft = "nl.microsoft";
public const string NoLucene = "no.lucene";
public const string PaMicrosoft = "pa.microsoft";
public const string Pattern = "pattern";
public const string PlLucene = "pl.lucene";
public const string PlMicrosoft = "pl.microsoft";
public const string PtBrLucene = "pt-BR.lucene";
public const string PtBrMicrosoft = "pt-BR.microsoft";
public const string PtPtLucene = "pt-PT.lucene";
public const string PtPtMicrosoft = "pt-PT.microsoft";
public const string RoLucene = "ro.lucene";
public const string RoMicrosoft = "ro.microsoft";
public const string RuLucene = "ru.lucene";
public const string RuMicrosoft = "ru.microsoft";
public const string Simple = "simple";
public const string SkMicrosoft = "sk.microsoft";
public const string SlMicrosoft = "sl.microsoft";
public const string SrCyrillicMicrosoft = "sr-cyrillic.microsoft";
public const string SrLatinMicrosoft = "sr-latin.microsoft";
public const string StandardAsciiFoldingLucene = "standardasciifolding.lucene";
public const string StandardLucene = "standard.lucene";
public const string Stop = "stop";
public const string SvLucene = "sv.lucene";
public const string SvMicrosoft = "sv.microsoft";
public const string TaMicrosoft = "ta.microsoft";
public const string TeMicrosoft = "te.microsoft";
public const string ThLucene = "th.lucene";
public const string ThMicrosoft = "th.microsoft";
public const string TrLucene = "tr.lucene";
public const string TrMicrosoft = "tr.microsoft";
public const string UkMicrosoft = "uk.microsoft";
public const string UrMicrosoft = "ur.microsoft";
public const string ViMicrosoft = "vi.microsoft";
public const string Whitespace = "whitespace";
public const string ZhHansLucene = "zh-Hans.lucene";
public const string ZhHansMicrosoft = "zh-Hans.microsoft";
public const string ZhHantLucene = "zh-Hant.lucene";
public const string ZhHantMicrosoft = "zh-Hant.microsoft";
}
}
public partial class LexicalTokenizer
{
Expand Down Expand Up @@ -1163,7 +1290,7 @@ public SearchIndex(string name, System.Collections.Generic.IEnumerable<Azure.Sea
public string DefaultScoringProfile { get { throw null; } set { } }
public Azure.Search.Documents.Indexes.Models.SearchResourceEncryptionKey EncryptionKey { get { throw null; } set { } }
public Azure.ETag? ETag { get { throw null; } set { } }
public System.Collections.Generic.IList<Azure.Search.Documents.Indexes.Models.SearchField> Fields { get { throw null; } }
public System.Collections.Generic.IList<Azure.Search.Documents.Indexes.Models.SearchField> Fields { get { throw null; } set { } }
heaths marked this conversation as resolved.
Show resolved Hide resolved
public string Name { get { throw null; } }
public System.Collections.Generic.IList<Azure.Search.Documents.Indexes.Models.ScoringProfile> ScoringProfiles { get { throw null; } }
public Azure.Search.Documents.Indexes.Models.SimilarityAlgorithm Similarity { get { throw null; } set { } }
Expand Down
1 change: 1 addition & 0 deletions sdk/search/Azure.Search.Documents/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ description: Samples for the Azure.Search.Documents client library
- Get started either [synchronously](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/search/Azure.Search.Documents/samples/Sample01a_HelloWorld.md) or [asynchronously](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/search/Azure.Search.Documents/samples/Sample01b_HelloWorldAsync.md).
- Perform [service level operations](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/search/Azure.Search.Documents/samples/Sample02_Service.md).
- Perform [index level operations](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/search/Azure.Search.Documents/samples/Sample03_Index.md).
- Build a Search index from a model using [FieldBuilder](Sample04_FieldBuilder.md).

## Sample Code to Include in your Projects

Expand Down
Loading