opción
HogarHogar Skill Herramientas para desarrolladores azure-search-documents-dotnet

azure-search-documents-dotnet

microsoft/skills microsoft/skills

Crea aplicaciones de búsqueda con búsqueda de texto completo, vectorial, semántica e híbrida utilizando el SDK de Azure AI Search para .NET.

...Expandir todo
0
Tiempo actualizado 15 de septiembre de 2026

Azure.Search.Documents (.NET)

Crea aplicaciones de búsqueda con capacidades de búsqueda de texto completo, vectorial, semántica e híbrida.

Instalación

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

Versiones actuales: Estable v11.7.0, Versión preliminar v11.8.0-beta.1

Variables de entorno

SEARCH_ENDPOINT=https://.search.windows.net  # Obligatorio: punto final del servicio de búsqueda
SEARCH_INDEX_NAME= # Obligatorio: nombre del índice de búsqueda
AZURE_TOKEN_CREDENTIALS=prod  # Obligatorio solo si se utiliza DefaultAzureCredential en producción
SEARCH_API_KEY= # Solo es necesario para la autenticación con AzureKeyCredential

Autenticación

Credencial de token de Microsoft Entra:

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

// Desarrollo local: DefaultAzureCredential. Producción: establece AZURE_TOKEN_CREDENTIALS=prod o AZURE_TOKEN_CREDENTIALS=
var credential = new DefaultAzureCredential(
    DefaultAzureCredential.DefaultEnvironmentVariableName
);
// O bien, utiliza una credencial específica directamente en producción:
// Consulta 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);

Clave de 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);

Selección de cliente

Cliente Finalidad
SearchClient Consultar índices, cargar/actualizar/eliminar documentos
SearchIndexClient Crear y gestionar índices y mapas de sinónimos
SearchIndexerClient Gestionar indexadores, conjuntos de habilidades y fuentes de datos

Creación de índices

Uso de FieldBuilder (recomendado)

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

// Definir el modelo con atributos
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; }
}

// Crear índice
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);

Definición manual de campos

var index = new SearchIndex("hotels")
{
    Campos =
    {
        nuevo SimpleField("hotelId", SearchFieldDataType.String) { IsKey = true, IsFilterable = true },
        nuevo 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"
        }
    }
};

Operaciones con documentos

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

// Carga (añadir nuevo)
var hotels = new[] { new Hotel { HotelId = "1", HotelName = "Hotel A" } };
await searchClient.UploadDocumentsAsync(hotels);

// Fusionar (actualizar los existentes)
await searchClient.MergeDocumentsAsync(hotels);

// Fusionar o cargar (upsert)
await searchClient.MergeOrUploadDocumentsAsync(hotels);

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

// Operaciones por lotes
var batch = IndexDocumentsBatch.Create(
    IndexDocumentsAction.Upload(hotel1),
    IndexDocumentsAction.Merge(hotel2),
    IndexDocumentsAction.Delete(hotel3));
await searchClient.IndexDocumentsAsync(batch);

Patrones de búsqueda

Búsqueda básica

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

Resultados de búsqueda results = await searchClient.SearchAsync("luxury", options);

Console.WriteLine($"Total: {results.TotalCount}");
await foreach (SearchResult result in results.GetResultsAsync())
{
    Console.WriteLine($"{result.Document.HotelName} (Puntuación: {result.Score})");
}

Búsqueda por facetas

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

Autocompletado y sugerencias

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

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

Búsqueda vectorial

Consulte references/vector-search.md para ver los patrones detallados.

using Azure.Search.Documents.Models;

// Búsqueda vectorial pura
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);

Búsqueda semántica

Consulta references/semantic-search.md para ver los patrones detallados.

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("el mejor hotel para familias", options);

// Acceder a las respuestas semánticas
foreach (var respuesta in results.Value.SemanticSearch.Answers)
{
    Console.WriteLine($"Respuesta: {respuesta.Text} (Puntuación: {respuesta.Score})");
}

// Acceder a los pies de foto
await foreach (var result in results.Value.GetResultsAsync())
{
    var caption = result.SemanticSearch?.Captions?.FirstOrDefault();
    Console.WriteLine($"Pie de foto: {caption?.Text}");
}

Búsqueda híbrida (vector + palabra clave + semántica)

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

// Combina la búsqueda por palabra clave, la búsqueda vectorial y la clasificación semántica
var results = await searchClient.SearchAsync("luxury beachfront", options);

Referencia de atributos de campo

Atributo Finalidad
SimpleField Campo no buscable (filtros, ordenación, facetas)
Campo de búsqueda Campo con búsqueda de texto completo
Campo de búsqueda vectorial Campo de incrustación vectorial
IsKey = true Clave del documento (obligatoria, una por índice)
IsFilterable = true Habilitar expresiones $filter
IsSortable = true Habilitar $orderby
IsFacetable = true Habilitar la navegación por facetas
IsHidden = true Excluir de los resultados
AnalyzerName Especificar analizador de texto

Gestión de errores

using Azure;

try
{
    var results = await searchClient.SearchAsync("query");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("Índice no encontrado");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"Error de búsqueda: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}

Prácticas recomendadas

  1. Utiliza DefaultAzureCredential en lugar de claves de API para el entorno de producción
  2. Utiliza FieldBuilder con atributos de modelo para definiciones de índices seguras en cuanto al tipo
  3. Utiliza CreateOrUpdateIndexAsync para la creación idempotente de índices
  4. Agrupa las operaciones con documentos para mejorar el rendimiento
  5. Utilizar Select para devolver solo los campos necesarios
  6. Configurar la búsqueda semántica para consultas en lenguaje natural
  7. Combina vectores, palabras clave y semántica para obtener la mejor relevancia

Archivos de referencia

Archivo Contenido
references/vector-search.md Búsqueda vectorial, búsqueda híbrida, vectorizadores
referencias/búsqueda-semántica.md Clasificación semántica, pies de foto, respuestas
Ver en GitHub
---
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 |

Todos los archivos

0 archivos

Instalar azure-search-documents-dotnet

Descarga y descomprime los archivos de habilidades en tu directorio .claude/skills/.

Descargar ZIP

Clona el repositorio y copia los archivos de la habilidad a tu proyecto.

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

Copiar Copiar
Configuración rápida: Copia la carpeta de la habilidad en .claude/skills/ Claude detectará y utilizará automáticamente la habilidad
Repositorio microsoft/skills

Habilidades relacionadas

algorithmic-art
Tiempo actualizado 27 de agosto de 2026
receiving-code-review
Tiempo actualizado 3 de septiembre de 2026
tech-debt-tracker
Tiempo actualizado 29 de agosto de 2026
deprecation-and-migration
Tiempo actualizado 3 de septiembre de 2026
OR