Azure Search Documents Dotnet

by microsoft354361d83247MITListed Oct 8, 2026Updated Oct 8, 2026

Azure AI Search SDK for .NET (Azure.Search.Documents). Use for building search applications with full-text, vector, semantic, and hybrid search. Covers SearchClient (queries, document CRUD), SearchIndexClient (index management), and SearchIndexerClient (indexers, skillsets). Triggers: "Azure Search .NET", "SearchClient", "SearchIndexClient", "vector search C#", "semantic search .NET", "hybrid search", "Azure.Search.Documents".

FeaturedInstructions onlySoftware Development
AI-generated overview

Guides .NET developers in using the Azure.Search.Documents SDK for full-text, vector, semantic and hybrid search.

What it does
This skill provides reference instructions and code examples for building search applications with the Azure AI Search SDK for .NET (Azure.Search.Documents). It covers client selection (SearchClient, SearchIndexClient, SearchIndexerClient), index creation with FieldBuilder or manual field definitions, document CRUD and batch operations, and query patterns including basic, faceted, autocomplete, vector, semantic and hybrid search. It also includes authentication setup, error handling and best practices, with two reference files on vector and semantic search.
When to use it
Use this skill when writing or reviewing C#/.NET code that queries or manages an Azure AI Search service. It fits tasks such as defining search indexes, uploading or deleting documents, and implementing vector, semantic or hybrid search queries.
Requirements
Requires the .NET SDK and the Azure.Search.Documents NuGet package, plus Azure.Identity for token credentials. Needs an Azure AI Search service endpoint and index name, and either Microsoft Entra credentials or an API key. Ships no scripts; it is instructions and reference documents only.

Azure.Search.Documents (.NET)

Build search applications with full-text, vector, semantic, and hybrid search capabilities.

Installation

bash
dotnet add package Azure.Search.Documentsdotnet add package Azure.Identity

Current Versions: Stable v11.7.0, Preview v11.8.0-beta.1

Environment Variables

bash
SEARCH_ENDPOINT=https://<search-service>.search.windows.net  # Required: search service endpointSEARCH_INDEX_NAME=<index-name>  # Required: search index nameAZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in productionSEARCH_API_KEY=<api-key>  # Only required for AzureKeyCredential auth

Authentication

Microsoft Entra Token Credential:

csharp
using Azure.Identity;using Azure.Search.Documents;
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>var credential = new DefaultAzureCredential(    DefaultAzureCredential.DefaultEnvironmentVariableName);// Or use a specific credential directly in production:// See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes// var credential = new ManagedIdentityCredential();var client = new SearchClient(    new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT")),    Environment.GetEnvironmentVariable("SEARCH_INDEX_NAME"),    credential);

API Key:

csharp
using Azure;using Azure.Search.Documents;
var credential = new AzureKeyCredential(    Environment.GetEnvironmentVariable("SEARCH_API_KEY"));var client = new SearchClient(    new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT")),    Environment.GetEnvironmentVariable("SEARCH_INDEX_NAME"),    credential);

Client Selection

ClientPurpose
SearchClientQuery indexes, upload/update/delete documents
SearchIndexClientCreate/manage indexes, synonym maps
SearchIndexerClientManage indexers, skillsets, data sources

Index Creation

Using FieldBuilder (Recommended)

csharp
using Azure.Search.Documents.Indexes;using Azure.Search.Documents.Indexes.Models;
// Define model with attributespublic class Hotel{    [SimpleField(IsKey = true, IsFilterable = true)]    public string HotelId { get; set; }
    [SearchableField(IsSortable = true)]    public string HotelName { get; set; }
    [SearchableField(AnalyzerName = LexicalAnalyzerName.EnLucene)]    public string Description { get; set; }
    [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]    public double? Rating { get; set; }
    [VectorSearchField(VectorSearchDimensions = 1536, VectorSearchProfileName = "vector-profile")]    public ReadOnlyMemory<float>? DescriptionVector { get; set; }}
// Create indexvar indexClient = new SearchIndexClient(endpoint, credential);var fieldBuilder = new FieldBuilder();var fields = fieldBuilder.Build(typeof(Hotel));
var index = new SearchIndex("hotels"){    Fields = fields,    VectorSearch = new VectorSearch    {        Profiles = { new VectorSearchProfile("vector-profile", "hnsw-algo") },        Algorithms = { new HnswAlgorithmConfiguration("hnsw-algo") }    }};
await indexClient.CreateOrUpdateIndexAsync(index);

Manual Field Definition

csharp
var index = new SearchIndex("hotels"){    Fields =    {        new SimpleField("hotelId", SearchFieldDataType.String) { IsKey = true, IsFilterable = true },        new SearchableField("hotelName") { IsSortable = true },        new SearchableField("description") { AnalyzerName = LexicalAnalyzerName.EnLucene },        new SimpleField("rating", SearchFieldDataType.Double) { IsFilterable = true, IsSortable = true },        new SearchField("descriptionVector", SearchFieldDataType.Collection(SearchFieldDataType.Single))        {            VectorSearchDimensions = 1536,            VectorSearchProfileName = "vector-profile"        }    }};

Document Operations

csharp
var searchClient = new SearchClient(endpoint, indexName, credential);
// Upload (add new)var hotels = new[] { new Hotel { HotelId = "1", HotelName = "Hotel A" } };await searchClient.UploadDocumentsAsync(hotels);
// Merge (update existing)await searchClient.MergeDocumentsAsync(hotels);
// Merge or Upload (upsert)await searchClient.MergeOrUploadDocumentsAsync(hotels);
// Deleteawait searchClient.DeleteDocumentsAsync("hotelId", new[] { "1", "2" });
// Batch operationsvar batch = IndexDocumentsBatch.Create(    IndexDocumentsAction.Upload(hotel1),    IndexDocumentsAction.Merge(hotel2),    IndexDocumentsAction.Delete(hotel3));await searchClient.IndexDocumentsAsync(batch);

Search Patterns

Basic Search

csharp
var options = new SearchOptions{    Filter = "rating ge 4",    OrderBy = { "rating desc" },    Select = { "hotelId", "hotelName", "rating" },    Size = 10,    Skip = 0,    IncludeTotalCount = true};
SearchResults<Hotel> results = await searchClient.SearchAsync<Hotel>("luxury", options);
Console.WriteLine($"Total: {results.TotalCount}");await foreach (SearchResult<Hotel> result in results.GetResultsAsync()){    Console.WriteLine($"{result.Document.HotelName} (Score: {result.Score})");}

Faceted Search

csharp
var options = new SearchOptions{    Facets = { "rating,count:5", "category" }};
var results = await searchClient.SearchAsync<Hotel>("*", options);
foreach (var facet in results.Value.Facets["rating"]){    Console.WriteLine($"Rating {facet.Value}: {facet.Count}");}

Autocomplete and Suggestions

csharp
// Autocompletevar autocompleteOptions = new AutocompleteOptions { Mode = AutocompleteMode.OneTermWithContext };var autocomplete = await searchClient.AutocompleteAsync("lux", "suggester-name", autocompleteOptions);
// Suggestionsvar suggestOptions = new SuggestOptions { UseFuzzyMatching = true };var suggestions = await searchClient.SuggestAsync<Hotel>("lux", "suggester-name", suggestOptions);

Vector Search

See references/vector-search.md [blocked] for detailed patterns.

csharp
using Azure.Search.Documents.Models;
// Pure vector searchvar vectorQuery = new VectorizedQuery(embedding){    KNearestNeighborsCount = 5,    Fields = { "descriptionVector" }};
var options = new SearchOptions{    VectorSearch = new VectorSearchOptions    {        Queries = { vectorQuery }    }};
var results = await searchClient.SearchAsync<Hotel>(null, options);

Semantic Search

See references/semantic-search.md [blocked] for detailed patterns.

csharp
var options = new SearchOptions{    QueryType = SearchQueryType.Semantic,    SemanticSearch = new SemanticSearchOptions    {        SemanticConfigurationName = "my-semantic-config",        QueryCaption = new QueryCaption(QueryCaptionType.Extractive),        QueryAnswer = new QueryAnswer(QueryAnswerType.Extractive)    }};
var results = await searchClient.SearchAsync<Hotel>("best hotel for families", options);
// Access semantic answersforeach (var answer in results.Value.SemanticSearch.Answers){    Console.WriteLine($"Answer: {answer.Text} (Score: {answer.Score})");}
// Access captionsawait foreach (var result in results.Value.GetResultsAsync()){    var caption = result.SemanticSearch?.Captions?.FirstOrDefault();    Console.WriteLine($"Caption: {caption?.Text}");}

Hybrid Search (Vector + Keyword + Semantic)

csharp
var vectorQuery = new VectorizedQuery(embedding){    KNearestNeighborsCount = 5,    Fields = { "descriptionVector" }};
var options = new SearchOptions{    QueryType = SearchQueryType.Semantic,    SemanticSearch = new SemanticSearchOptions    {        SemanticConfigurationName = "my-semantic-config"    },    VectorSearch = new VectorSearchOptions    {        Queries = { vectorQuery }    }};
// Combines keyword search, vector search, and semantic rankingvar results = await searchClient.SearchAsync<Hotel>("luxury beachfront", options);

Field Attributes Reference

AttributePurpose
SimpleFieldNon-searchable field (filters, sorting, facets)
SearchableFieldFull-text searchable field
VectorSearchFieldVector embedding field
IsKey = trueDocument key (required, one per index)
IsFilterable = trueEnable $filter expressions
IsSortable = trueEnable $orderby
IsFacetable = trueEnable faceted navigation
IsHidden = trueExclude from results
AnalyzerNameSpecify text analyzer

Error Handling

csharp
using Azure;
try{    var results = await searchClient.SearchAsync<Hotel>("query");}catch (RequestFailedException ex) when (ex.Status == 404){    Console.WriteLine("Index not found");}catch (RequestFailedException ex){    Console.WriteLine($"Search error: {ex.Status} - {ex.ErrorCode}: {ex.Message}");}

Best Practices

  1. Use DefaultAzureCredential over API keys for production
  2. Use FieldBuilder with model attributes for type-safe index definitions
  3. Use CreateOrUpdateIndexAsync for idempotent index creation
  4. Batch document operations for better throughput
  5. Use Select to return only needed fields
  6. Configure semantic search for natural language queries
  7. Combine vector + keyword + semantic for best relevance

Reference Files

FileContents
references/vector-search.md [blocked]Vector search, hybrid search, vectorizers
references/semantic-search.md [blocked]Semantic ranking, captions, answers

Source and attribution

Source:microsoft/skillsin.github/plugins/azure-sdk-dotnet/skills/azure-search-documents-dotnetat commit354361d

License: MIT

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal