Option
HeimHeim Skill Entwicklertools azure-search-documents-dotnet

azure-search-documents-dotnet

microsoft/skills microsoft/skills

Erstellen Sie Suchanwendungen mit Volltext-, Vektor-, semantischer und hybrider Suche mithilfe des Azure AI Search SDK für .NET.

...Alle erweitern
0
Zeit aktualisiert 15. September 2026

Azure.Search.Documents (.NET)

Erstellen Sie Suchanwendungen mit Volltext-, Vektor-, semantischen und hybriden Suchfunktionen.

Installation

dotnet add package Azure.Search.Documents
dotnet add package Azure.Identity

Aktuelle Versionen: Stable v11.7.0, Preview v11.8.0-beta.1

Umgebungsvariablen

SEARCH_ENDPOINT=https://.search.windows.net  # Erforderlich: Endpunkt des Suchdienstes
SEARCH_INDEX_NAME= # Erforderlich: Name des Suchindexes
AZURE_TOKEN_CREDENTIALS=prod  # Nur erforderlich, wenn „DefaultAzureCredential“ in der Produktion verwendet wird
SEARCH_API_KEY= # Nur für die Authentifizierung mit „AzureKeyCredential“ erforderlich

Authentifizierung

Microsoft Entra-Token-Anmeldeinformationen:

using Azure.Identity;
using Azure.Search.Documents;

// Lokale Entwicklung: „DefaultAzureCredential“. Produktion: Setze AZURE_TOKEN_CREDENTIALS=prod oder AZURE_TOKEN_CREDENTIALS=
var credential = new DefaultAzureCredential(
    DefaultAzureCredential.DefaultEnvironmentVariableName
);
// Oder verwenden Sie in der Produktion direkt eine bestimmte Anmeldeinformation:
// Siehe 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-Schlüssel:

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-Auswahl

Client Zweck
SearchClient Indizes abfragen, Dokumente hochladen/aktualisieren/löschen
SearchIndexClient Indizes und Synonymzuordnungen erstellen/verwalten
SearchIndexerClient Indexer, Skillsets und Datenquellen verwalten

Indexerstellung

Verwendung von FieldBuilder (empfohlen)

using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;

// Modell mit Attributen definieren
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; }
}

// Index erstellen
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);

Manuelle Felddefinition

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"
        }
    }
};

Dokumentoperationen

var searchClient = new SearchClient(endpoint, indexName, credential);

// Hochladen (neu hinzufügen)
var hotels = new[] { new Hotel { HotelId = "1", HotelName = "Hotel A" } };
await searchClient.UploadDocumentsAsync(hotels);

// Zusammenführen (vorhandene aktualisieren)
await searchClient.MergeDocumentsAsync(hotels);

// Zusammenführen oder hochladen (Upsert)
await searchClient.MergeOrUploadDocumentsAsync(hotels);

// Löschen
await searchClient.DeleteDocumentsAsync("hotelId", new[] { "1", "2" });

// Batch-Operationen
var batch = IndexDocumentsBatch.Create(
    IndexDocumentsAction.Upload(hotel1),
    IndexDocumentsAction.Merge(hotel2),
    IndexDocumentsAction.Delete(hotel3));
await searchClient.IndexDocumentsAsync(batch);

Suchmuster

Einfache Suche

var options = new SearchOptions
{
    Filter = "rating ge 4",
    OrderBy = { "rating desc" },
    Select = { "hotelId", "hotelName", "rating" },
    Size = 10,
    Skip = 0,
    IncludeTotalCount = true
};

Suchergebnisse results = await searchClient.SearchAsync("luxury", options);

Console.WriteLine($"Gesamt: {results.TotalCount}");
await foreach (SearchResult result in results.GetResultsAsync())
{
    Console.WriteLine($"{result.Document.HotelName} (Bewertung: {result.Score})");
}

Facettensuche

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($"Bewertung {facet.Value}: {facet.Count}");
}

Autovervollständigung und Vorschläge

// Autovervollständigung
var autocompleteOptions = new AutocompleteOptions { Mode = AutocompleteMode.OneTermWithContext };
var autocomplete = await searchClient.AutocompleteAsync("lux", "suggester-name", autocompleteOptions);

// Vorschläge
var suggestOptions = new SuggestOptions { UseFuzzyMatching = true };
var suggestions = await searchClient.SuggestAsync("lux", "suggester-name", suggestOptions);

Vektorsuche

Detaillierte Muster finden Sie in „references/vector-search.md“.

using Azure.Search.Documents.Models;

// Reine Vektorsuche
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);

Semantische Suche

Detaillierte Muster finden Sie unter „references/semantic-search.md“.

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("bestes Hotel für Familien", options);

// Auf semantische Antworten zugreifen
foreach (var answer in results.Value.SemanticSearch.Answers)
{
    Console.WriteLine($"Antwort: {answer.Text} (Bewertung: {answer.Score})");
}

// Auf Bildunterschriften zugreifen
await foreach (var result in results.Value.GetResultsAsync())
{
    var caption = result.SemanticSearch?.Captions?.FirstOrDefault();
    Console.WriteLine($"Bildunterschrift: {caption?.Text}");
}

Hybride Suche (Vektor + Schlüsselwort + Semantik)

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 }
    }
};

// Kombiniert Stichwortsuche, Vektorsuche und semantisches Ranking
var results = await searchClient.SearchAsync("luxury beachfront", options);

Referenz zu Feldattributen

Attribut Zweck
SimpleField Nicht durchsuchbares Feld (Filter, Sortierung, Facetten)
SearchableField Volltextdurchsuchbares Feld
Vektor-Suchfeld Vektor-Embedding-Feld
IsKey = true Dokumentenschlüssel (erforderlich, einer pro Index)
IsFilterable = true $filter-Ausdrücke aktivieren
IsSortable = true $orderby aktivieren
IsFacetable = true Facettierte Navigation aktivieren
IsHidden = true Aus den Ergebnissen ausschließen
AnalyzerName Textanalysator angeben

Fehlerbehandlung

using Azure;

try
{
    var results = await searchClient.SearchAsync("query");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("Index nicht gefunden");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"Suchfehler: {ex.Status} – {ex.ErrorCode}: {ex.Message}");
}

Bewährte Vorgehensweisen

  1. Verwenden Sie in der Produktion „DefaultAzureCredential“ anstelle von API-Schlüsseln
  2. Verwenden Sie „FieldBuilder“ mit Modellattributen für typsichere Indexdefinitionen
  3. Verwenden Sie „CreateOrUpdateIndexAsync“ für die idempotente Indexerstellung
  4. Führen SieDokumentoperationen im Batch aus, um einen besseren Durchsatz zu erzielen
  5. Verwenden Sie „Select“, um nur benötigte Felder zurückzugeben
  6. Konfigurieren Sie die semantische Suche für Abfragen in natürlicher Sprache
  7. Kombinieren Sie Vektor, Schlüsselwörter und Semantik für beste Relevanz

Referenzdateien

Datei Inhalt
references/vector-search.md Vektorsuche, hybride Suche, Vektorisierer
references/semantic-search.md Semantisches Ranking, Bildunterschriften, Antworten
Auf GitHub ansehen
---
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 |

Alle Dateien

0 Dateien

azure-search-documents-dotnet installieren

Laden Sie die Skill-Dateien herunter und entpacken Sie sie in Ihr Verzeichnis „.claude/skills/“.

ZIP herunterladen

Klonen Sie das Repository und kopieren Sie die Skill-Dateien in Ihr Projekt.

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

Kopieren Kopieren
Schnelle Einrichtung: Kopiere den Skill-Ordner nach .claude/skills/ Claude erkennt den Skill automatisch und nutzt ihn.
Repository microsoft/skills

Ähnliche Skills

algorithmic-art
Zeit aktualisiert 27. August 2026
receiving-code-review
Zeit aktualisiert 3. September 2026
tech-debt-tracker
Zeit aktualisiert 29. August 2026
deprecation-and-migration
Zeit aktualisiert 3. September 2026
OR