azure-search-documents-dotnet
microsoft/skills
Créez des applications de recherche avec des fonctionnalités de recherche en texte intégral, vectorielle, sémantique et hybride à l'aide du SDK Azure AI Search pour .NET.
...Développer toutAzure.Search.Documents (.NET)
Créez des applications de recherche dotées de fonctionnalités de recherche en texte intégral, vectorielle, sémantique et hybride.
Installation
dotnet add package Azure.Search.Documents
dotnet add package Azure.Identity
Versions actuelles: Stable v11.7.0, Préversion v11.8.0-beta.1
Variables d'environnement
SEARCH_ENDPOINT=https://.search.windows.net # Obligatoire : point de terminaison du service de recherche
SEARCH_INDEX_NAME= # Obligatoire : nom de l’index de recherche
AZURE_TOKEN_CREDENTIALS=prod # Obligatoire uniquement si DefaultAzureCredential est utilisé en production
SEARCH_API_KEY= # Obligatoire uniquement pour l’authentification AzureKeyCredential
Authentification
Identifiants de jeton Microsoft Entra:
using Azure.Identity;
using Azure.Search.Documents;
// Développement local : DefaultAzureCredential. En production : définissez AZURE_TOKEN_CREDENTIALS=prod ou AZURE_TOKEN_CREDENTIALS=
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
// Ou utilisez directement des informations d'identification spécifiques en production :
// Voir 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);
Clé API:
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);
Sélection du client
| Client | Objectif |
|---|---|
SearchClient |
Interroger des index, charger/mettre à jour/supprimer des documents |
SearchIndexClient |
Créer/gérer des index, des tables de synonymes |
SearchIndexerClient |
Gérer les indexeurs, les ensembles de compétences et les sources de données |
Création d’index
Utilisation de FieldBuilder (recommandé)
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
// Définir un modèle avec des attributs
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? DescriptionVector { get; set; }
}
// Créer un 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);
Définition manuelle des champs
var index = new SearchIndex("hotels")
{
Champs =
{
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"
}
}
};
Opérations sur les documents
var searchClient = new SearchClient(endpoint, indexName, credential);
// Téléchargement (ajout d’un nouveau document)
var hotels = new[] { new Hotel { HotelId = "1", HotelName = "Hôtel A" } };
await searchClient.UploadDocumentsAsync(hotels);
// Fusion (mise à jour d'un document existant)
await searchClient.MergeDocumentsAsync(hotels);
// Fusion ou ajout (upsert)
await searchClient.MergeOrUploadDocumentsAsync(hotels);
// Suppression
await searchClient.DeleteDocumentsAsync("hotelId", new[] { "1", "2" });
// Opérations par lots
var batch = IndexDocumentsBatch.Create(
IndexDocumentsAction.Upload(hotel1),
IndexDocumentsAction.Merge(hotel2),
IndexDocumentsAction.Delete(hotel3));
await searchClient.IndexDocumentsAsync(batch);
Modèles de recherche
Recherche de base
var options = new SearchOptions
{
Filter = "rating ge 4",
OrderBy = { "rating desc" },
Select = { "hotelId", "hotelName", "rating" },
Size = 10,
Skip = 0,
IncludeTotalCount = true
};
s de recherche results = await searchClient.SearchAsync("luxury", options);
Console.WriteLine($"Total : {results.TotalCount}");
await foreach (SearchResult result in results.GetResultsAsync())
{
Console.WriteLine($"{result.Document.HotelName} (Note : {result.Score})");
}
Recherche par facettes
var options = new SearchOptions
{
Facets = { "rating,count:5", "category" }
};
var results = await searchClient.SearchAsync("*", options);
foreach (var facet in results.Value.Facets["rating"])
{
Console.WriteLine($"Note {facet.Value} : {facet.Count}");
}
Saisie semi-automatique et suggestions
// Saisie semi-automatique
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("lux", "suggester-name", suggestOptions);
Recherche vectorielle
Voir references/vector-search.md pour les modèles détaillés.
using Azure.Search.Documents.Models;
// Recherche vectorielle pure
var vectorQuery = new VectorizedQuery(embedding)
{
KNearestNeighborsCount = 5,
Fields = { "descriptionVector" }
};
var options = new SearchOptions
{
VectorSearch = new VectorSearchOptions
{
Queries = { vectorQuery }
}
};
var results = await searchClient.SearchAsync(null, options);
Recherche sémantique
Voir references/semantic-search.md pour les modèles détaillés.
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("meilleur hôtel pour les familles", options);
// Accéder aux réponses sémantiques
foreach (var answer in results.Value.SemanticSearch.Answers)
{
Console.WriteLine($"Réponse : {answer.Text} (Score : {answer.Score})");
}
// Accéder aux légendes
await foreach (var result in results.Value.GetResultsAsync())
{
var caption = result.SemanticSearch?.Captions?.FirstOrDefault();
Console.WriteLine($"Légende : {caption?.Text}");
}
Recherche hybride (vecteur + mot-clé + sémantique)
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 }
}
};
// Combine la recherche par mot-clé, la recherche vectorielle et le classement sémantique
var results = await searchClient.SearchAsync("luxury beachfront", options);
Référence des attributs de champ
| Attribut | Objectif |
|---|---|
SimpleField |
Champ non consultable (filtres, tri, facettes) |
Champ de recherche |
Champ consultable en texte intégral |
Champ de recherche vectorielle |
Champ d'intégration vectorielle |
IsKey = true |
Clé de document (obligatoire, une par index) |
IsFilterable = true |
Activer les expressions $filter |
IsSortable = true |
Activer $orderby |
IsFacetable = true |
Activer la navigation par facettes |
IsHidden = true |
Exclure des résultats |
AnalyzerName |
Spécifier l'analyseur de texte |
Gestion des erreurs
using Azure;
try
{
var results = await searchClient.SearchAsync("query");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
Console.WriteLine("Index introuvable");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Erreur de recherche : {ex.Status} - {ex.ErrorCode} : {ex.Message}");
}
Bonnes pratiques
- Utilisez
DefaultAzureCredentialplutôt que les clés d’API en production - Utilisez
FieldBuilderavec les attributs de modèle pour des définitions d’index sans risque de type - Utilisez
CreateOrUpdateIndexAsyncpour la création d'index idempotente - Regroupez les opérations sur les documents pour un meilleur débit
- Utilisez
Selectpour ne renvoyer que les champs nécessaires - Configurer la recherche sémantique pour les requêtes en langage naturel
- Combiner la recherche vectorielle, par mots-clés et sémantique pour une pertinence optimale
Fichiers de référence
| Fichier | Contenu |
|---|---|
| references/vector-search.md | Recherche vectorielle, recherche hybride, vectoriseurs |
| references/semantic-search.md | Classement sémantique, légendes, réponses |
---
name: azure-search-documents-dotnet
description: Build search applications with full-text, vector, semantic, and hybrid search using the Azure AI Search SDK for .NET.
license: MIT
---
# 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 # Required: search service endpoint
SEARCH_INDEX_NAME=<index-name> # Required: search index name
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
SEARCH_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
| 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](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](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](references/vector-search.md) | Vector search, hybrid search, vectorizers |
| [references/semantic-search.md](references/semantic-search.md) | Semantic ranking, captions, answers |
Tous les fichiers
0 fichiersInstaller azure-search-documents-dotnet
Téléchargez et décompressez les fichiers de compétences dans votre répertoire .claude/skills/.
Télécharger le ZIPClonez le dépôt et copiez les fichiers de compétence dans votre projet.
git clone https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-search-documents-dotnet # Copy SKILL.md to your .claude/skills/ directory
Copier





Maison
