azure-search-documents-dotnet
Azure AI Search SDK for .NET (Azure.Search.Documents). Use for building search applications with full-text, vector, semantic, and hybrid search.
Best use case
azure-search-documents-dotnet is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Azure AI Search SDK for .NET (Azure.Search.Documents). Use for building search applications with full-text, vector, semantic, and hybrid search.
Teams using azure-search-documents-dotnet should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/azure-search-documents-dotnet/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How azure-search-documents-dotnet Compares
| Feature / Agent | azure-search-documents-dotnet | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Azure AI Search SDK for .NET (Azure.Search.Documents). Use for building search applications with full-text, vector, semantic, and hybrid search.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Azure.Search.Documents (.NET)
Build search applications with full-text, vector, semantic, and hybrid search capabilities.
## Installation
```bash
dotnet add package Azure.Search.Documents
dotnet 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
SEARCH_INDEX_NAME=<index-name>
# For API key auth (not recommended for production)
SEARCH_API_KEY=<api-key>
```
## Authentication
**DefaultAzureCredential (preferred)**:
```csharp
using Azure.Identity;
using Azure.Search.Documents;
var credential = new DefaultAzureCredential();
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
| Client | Purpose |
|--------|---------|
| `SearchClient` | Query indexes, upload/update/delete documents |
| `SearchIndexClient` | Create/manage indexes, synonym maps |
| `SearchIndexerClient` | Manage indexers, skillsets, data sources |
## Index Creation
### Using FieldBuilder (Recommended)
```csharp
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
// Define model with attributes
public 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 index
var 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);
// Delete
await searchClient.DeleteDocumentsAsync("hotelId", new[] { "1", "2" });
// Batch operations
var 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
// Autocomplete
var autocompleteOptions = new AutocompleteOptions { Mode = AutocompleteMode.OneTermWithContext };
var autocomplete = await searchClient.AutocompleteAsync("lux", "suggester-name", autocompleteOptions);
// Suggestions
var suggestOptions = new SuggestOptions { UseFuzzyMatching = true };
var suggestions = await searchClient.SuggestAsync<Hotel>("lux", "suggester-name", suggestOptions);
```
## Vector Search
See references/vector-search.md for detailed patterns.
```csharp
using Azure.Search.Documents.Models;
// Pure vector search
var 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 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 answers
foreach (var answer in results.Value.SemanticSearch.Answers)
{
Console.WriteLine($"Answer: {answer.Text} (Score: {answer.Score})");
}
// Access captions
await 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 ranking
var results = await searchClient.SearchAsync<Hotel>("luxury beachfront", options);
```
## Field Attributes Reference
| Attribute | Purpose |
|-----------|---------|
| `SimpleField` | Non-searchable field (filters, sorting, facets) |
| `SearchableField` | Full-text searchable field |
| `VectorSearchField` | Vector embedding field |
| `IsKey = true` | Document key (required, one per index) |
| `IsFilterable = true` | Enable $filter expressions |
| `IsSortable = true` | Enable $orderby |
| `IsFacetable = true` | Enable faceted navigation |
| `IsHidden = true` | Exclude from results |
| `AnalyzerName` | Specify 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
| File | Contents |
|------|----------|
| references/vector-search.md | Vector search, hybrid search, vectorizers |
| references/semantic-search.md | Semantic ranking, captions, answers |
## When to Use
This skill is applicable to execute the workflow or actions described in the overview.Related Skills
azure-servicebus-dotnet
Azure Service Bus SDK for .NET. Enterprise messaging with queues, topics, subscriptions, and sessions.
azure-search-documents-ts
Build search applications using Azure AI Search SDK for JavaScript (@azure/search-documents). Use when creating/managing indexes, implementing vector/hybrid search, semantic ranking, or building ag...
azure-search-documents-py
Azure AI Search SDK for Python. Use for vector search, hybrid search, semantic ranking, indexing, and skillsets.
azure-role-selector
When user is asking for guidance for which role to assign to an identity given desired permissions, this agent helps them understand the role that will meet the requirements with least privilege access and how to apply that role.
azure-resource-visualizer
Analyze Azure resource groups and generate detailed Mermaid architecture diagrams showing the relationships between individual resources. Use this skill when the user asks for a diagram of their Azure resources or help in understanding how the resources relate to each other.
azure-resource-manager-sql-dotnet
Azure Resource Manager SDK for Azure SQL in .NET.
azure-resource-manager-redis-dotnet
Azure Resource Manager SDK for Redis in .NET.
azure-resource-manager-postgresql-dotnet
Azure PostgreSQL Flexible Server SDK for .NET. Database management for PostgreSQL Flexible Server deployments.
azure-resource-manager-playwright-dotnet
Azure Resource Manager SDK for Microsoft Playwright Testing in .NET.
azure-resource-manager-mysql-dotnet
Azure MySQL Flexible Server SDK for .NET. Database management for MySQL Flexible Server deployments.
azure-resource-manager-durabletask-dotnet
Azure Resource Manager SDK for Durable Task Scheduler in .NET.
azure-resource-manager-cosmosdb-dotnet
Azure Resource Manager SDK for Cosmos DB in .NET.