オプション
家 Skill 開発者ツール azure-search-documents-dotnet

azure-search-documents-dotnet

microsoft/skills microsoft/skills

Azure AI Search SDK for .NET を使用して、フルテキスト検索、ベクトル検索、セマンティック検索、およびハイブリッド検索機能を備えた検索アプリケーションを構築します。

...すべて拡張します
0
更新された時間 2026年9月15日

Azure.Search.Documents (.NET)

全文検索、ベクトル検索、セマンティック検索、およびハイブリッド検索機能を備えた検索アプリケーションを構築します。

インストール

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

現在のバージョン: 安定版 v11.7.0、プレビュー版 v11.8.0-beta.1

環境変数

SEARCH_ENDPOINT=https://.search.windows.net  # 必須: 検索サービスのエンドポイント
環境変数SEARCH_ENDPOINT=https:// .search.windows.net  # 必須: 検索サービスのエンドポイント
SEARCH_INDEX_NAME= # 必須: 検索インデックス名
AZURE_TOKEN_CREDENTIALS=prod  # 本番環境で DefaultAzureCredential を使用する場合にのみ必須
SEARCH_API_KEY= # AzureKeyCredential 認証の場合にのみ必須

認証

Microsoft Entra トークン資格情報:

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

// ローカル開発環境: DefaultAzureCredential。 本番環境: AZURE_TOKEN_CREDENTIALS=prod または AZURE_TOKEN_CREDENTIALS=に設定
var credential = new DefaultAzureCredential(
    DefaultAzureCredential.DefaultEnvironmentVariableName
);
// または、本番環境では特定の認証情報を直接使用することもできます:
// 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 キー:

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

クライアントの選択

クライアント 目的
SearchClient インデックスのクエリ、ドキュメントのアップロード/更新/削除
SearchIndexClient インデックスおよび同義語マップの作成・管理
SearchIndexerClient インデクサー、スキルセット、データソースの管理

インデックスの作成

FieldBuilder の使用(推奨)

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

// 属性を持つモデルを定義する
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; }
}

// インデックスの作成
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);

手動によるフィールド定義

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

ドキュメント操作

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

// アップロード(新規追加)
var hotels = new[] { new Hotel { HotelId = "1", HotelName = "Hotel A" } };
await searchClient.UploadDocumentsAsync(hotels);

// マージ(既存の更新)
await searchClient.MergeDocumentsAsync(hotels);

// マージまたはアップロード (アップサート)
await searchClient.MergeOrUploadDocumentsAsync(hotels);

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

// バッチ操作
var batch = IndexDocumentsBatch.Create(
    IndexDocumentsAction.Upload(hotel1),
    IndexDocumentsAction.Merge(hotel2),
    IndexDocumentsAction.Delete(hotel3));
await searchClient.IndexDocumentsAsync(batch);

検索パターン

基本検索

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

検索結果 results = await searchClient.SearchAsync("luxury", options);

Console.WriteLine($"合計: {results.TotalCount}");
await foreach (SearchResult result in results.GetResultsAsync())
{
    Console.WriteLine($"{result.Document.HotelName} (スコア: {result.Score})");
}

ファセット検索

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

オートコンプリートと候補表示

// オートコンプリート
var autocompleteOptions = new AutocompleteOptions { Mode = AutocompleteMode.OneTermWithContext };
var autocomplete = await searchClient.AutocompleteAsync("lux", "suggester-name", autocompleteOptions);

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

ベクトル検索

詳細なパターンについては、references/vector-search.md を参照してください。

using Azure.Search.Documents.Models;

// 純粋なベクトル検索
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);

セマンティック検索

詳細なパターンについては、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("best hotel for families", options);

// セマンティック検索の結果にアクセス
foreach (var answer in results.Value.SemanticSearch.Answers)
{
    Console.WriteLine($"回答: {answer.Text} (スコア: {answer.Score})");
}

// キャプションにアクセス
await foreach (var result in results.Value.GetResultsAsync())
{
    var caption = result.SemanticSearch?.Captions?.FirstOrDefault();
    Console.WriteLine($"キャプション: {caption?.Text}");
}

ハイブリッド検索(ベクトル + キーワード + セマンティック)

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

// キーワード検索、ベクトル検索、セマンティックランキングを組み合わせる
var results = await searchClient.SearchAsync("luxury beachfront", options);

フィールド属性リファレンス

属性 目的
SimpleField 検索対象外のフィールド(フィルタ、ソート、ファセット)
SearchableField 全文検索可能なフィールド
ベクトル検索フィールド ベクトル埋め込みフィールド
IsKey = true ドキュメントキー(必須、インデックスごとに1つ)
IsFilterable = true $filter 式を有効にする
IsSortable = true $orderby を有効にする
IsFacetable = true ファセットナビゲーションを有効にする
IsHidden = true 検索結果から除外
AnalyzerName テキストアナライザーを指定

エラー処理

using Azure;

try
{
    var results = await searchClient.SearchAsync("query");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("インデックスが見つかりません");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"検索エラー: {ex.Status} - {ex.ErrorCode}: {ex.Message}");
}

ベストプラクティス

  1. 本番環境では、APIキーの代わりに DefaultAzureCredentialを使用する
  2. 型安全なインデックス定義には、モデル属性と FieldBuilder を併用する
  3. 冪等なインデックス作成には ` CreateOrUpdateIndexAsync`を使用する
  4. スループット向上のためにドキュメント操作をバッチ処理する
  5. 必要なフィールドのみを返すには ` Select`を使用する
  6. 自然言語クエリに対応したセマンティック検索を設定する
  7. ベクトル+キーワード+セマンティックを組み合わせて、最適な関連性を実現する

参考ファイル

ファイル 目次
references/vector-search.md ベクトル検索、ハイブリッド検索、ベクトライザー
references/semantic-search.md セマンティックランキング、キャプション、回答
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 |

すべてのファイル

0件のファイル

azure-search-documents-dotnetをインストール

スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。

ZIPをダウンロード

リポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。

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

コピー コピー
クイックセットアップ: スキルフォルダを .claude/skills/ にコピーしてください。 Claude が自動的にそのスキルを検出して使用します。
リポジトリ microsoft/skills

関連スキル

algorithmic-art
更新された時間 2026年8月27日
receiving-code-review
更新された時間 2026年9月3日
tech-debt-tracker
更新された時間 2026年8月29日
deprecation-and-migration
更新された時間 2026年9月3日
OR