Azure Cognitive Search client library for .NET
Azure Cognitive Search is a search-as-a-service cloud solution that gives developers APIs and tools for adding a rich search experience over private, heterogeneous content in web, mobile, and enterprise applications.
The Azure Cognitive Search service is well suited for the following application scenarios:
- Consolidate varied content types into a single searchable index. Populate the index with your own JSON documents or, if your content is already in Azure, you can create an indexer to pull in data automatically.
- Import raw content such as text, images, or Office files from Azure Blob Storage or Cosmos DB.
- Easily implement your own search capabilities similar to commercial web search engines. Azure Cognitive Search APIs simplify query construction, faceted navigation, filters (including geo-spatial search), synonym mapping, typeahead queries, and relevance tuning.
- Index unstructured text and extract both text and information from images. AI enrichment enables capabilities such as OCR, entity recognition, key phrase extraction, language detection, text translation, and sentiment analysis.
Use the Azure.Search client library to:
- Create and manage search indexes.
- Upload and update documents in the search index.
- Manage indexers that pull data from a data source into an index.
- Query documents in the index with a powerful set of search APIs that support faceted navigation, typeahead queries, suggestions, and geo-spatial search.
- Enrich your search index with AI skills that add structure or extract meaning from raw documents during indexing.
Source code | Package (NuGet) | API reference documentation | REST API documentation | Product documentation
Getting started
Install the package
Install the Azure Cognitive Search client library for .NET with NuGet:
dotnet add package Azure.Search --version 11.0.0-preview.1
Prerequisites
You need an Azure subscription and a Search Service to use this package.
To create a new Search Service, you can use the Azure Portal, Azure PowerShell, or the Azure CLI. Here's an example using the Azure CLI to create a free instance for getting started:
az search service create --name <mysearch> --resource-group <mysearch-rg> --sku free --location westus
See choosing a pricing tier for more information about available options.
Get a Search api-key
All requests to a search service need an api-key that was generated specifically for your service. The api-key is the sole mechanism for authenticating access to your search service endpoint. You can obtain your api-key from the Azure Portal or via the Azure CLI:
az search admin-key show --service-name <mysearch> --resource-group <mysearch-rg>
There are two types of keys used to access your search service: admin (read-write) and query (read-only) keys. Restricting access and operations in client apps is essential to safeguarding the search assets on your service. Always use a query key rather than an admin key for any query originating from a client app.
Note: The example Azure CLI snippet above retrieves an admin key so it's easier to get started exploring APIs, but it should be managed carefully.
Send your first search query
To get running immediately, we're going to connect to a well known sandbox Search service provided by Microsoft. This means you do not need an Azure subscription or Azure Cognitive Search service to try out this query.
// We'll connect to the Azure Cognitive Search public sandbox and send a
// query to its "nycjobs" index built from a public dataset of available jobs
// in New York.
string serviceName = "azs-playground";
string indexName = "nycjobs";
string apiKey = "252044BE3886FE4A8E3BAA4F595114BB";
// Create a SearchIndexClient to send queries
Uri serviceEndpoint = new Uri($"https://{serviceName}.search.windows.net/");
SearchApiKeyCredential credential = new SearchApiKeyCredential(apiKey);
SearchIndexClient client = new SearchIndexClient(serviceEndpoint, indexName, credential);
// Let's get the top 5 jobs related to Microsoft
SearchResults<SearchDocument> response = client.Search("Microsoft", new SearchOptions { Size = 5 });
foreach (SearchResult<SearchDocument> result in response.GetResults())
{
// Print out the title and job description (we'll see below how to
// use C# objects to make accessing these fields much easier)
string title = (string)result.Document["business_title"];
string description = (string)result.Document["job_description"];
Console.WriteLine($"{title}\n{description}\n");
}
You can paste that into a new console app, install the Azure.Search package,
add a using Azure.Search;
statement, and then hit F5 to run.
Key concepts
An Azure Cognitive Search service contains one or more indexes that provide persistent storage of searchable data in the form of JSON documents. (If you're brand new to Search, you can make a very rough analogy between indexes and database tables.) The Azure.Search client library exposes operations on these resources through two main client types:
SearchIndexClient
helps with- Searching your indexed documents using rich queries and powerful data shaping
- Autocompleting partially typed search terms based on documents in the index
- Suggesting the most likely matching text in documents as a user types
- Adding, Updating or Deleting Documents documents from an index
SearchServiceClient
allows you to:- Create, delete, update, or configure a search index
- Start indexers to automatically crawl data sources
- Define AI powered Skillsets to transform and enrich your data
- Declare custom synonym maps to expand or rewrite queries
- Most of the
SearchServiceClient
functionality is not yet available in our current preview
The Azure.Search
client library (v11) is a brand new offering for .NET
developers who want to use search technology in their applications. There is an
older, fully featured Microsoft.Azure.Search
client library (v10) with many
similar looking APIs, so please be careful to avoid confusion when exploring
online resources. A good rule of thumb is to check for the namespace
using Azure.Search;
when you're looking for us.
Examples
The following examples all use a simple Hotel data set that you can import into your own index from the Azure Portal. These are just a few of the basics - please check out our Samples for much more.
Querying
Let's start by importing our namespace.
using Azure.Search;
We'll then create a SearchIndexClient
to access our hotels search index.
// Get the service endpoint and API key from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
string key = Environment.GetEnvironmentVariable("SEARCH_API_KEY");
string indexName = "hotels";
// Create a client
SearchApiKeyCredential credential = new SearchApiKeyCredential(key);
SearchIndexClient client = new SearchIndexClient(endpoint, indexName, credential);
There are three ways to interact with the data returned from a search query. Let's explore them with a search for a "luxury" hotel.
Use SearchDocument
like a dictionary
SearchDocument
is the default type returned from queries when you don't
provide your own. Here we perform the search, enumerate over the results, and
extract data using SearchDocument
's dictionary indexer.
SearchResults<SearchDocument> response = client.Search("luxury");
foreach (SearchResult<SearchDocument> result in response.GetResults())
{
SearchDocument doc = result.Document;
string id = (string)doc["hotelId"];
string name = (string)doc["hotelName"];
Console.WriteLine("{id}: {name}");
}
Use SearchDocument
with C#'s dynamic
keyword
This starts out the same, but the use of dynamic
makes the code a little
easier to read.
SearchResults<SearchDocument> response = client.Search("luxury");
foreach (SearchResult<SearchDocument> result in response.GetResults())
{
dynamic doc = result.Document;
string id = doc.hotelId;
string name = doc.hotelName;
Console.WriteLine("{id}: {name}");
}
Use C# types
We can also decorate our own types with attributes from System.Text.Json
public class Hotel
{
[JsonPropertyName("hotelId")]
public string Id { get; set; }
[JsonPropertyName("hotelName")]
public string Name { get; set; }
}
And use them in place of SearchDocument
when querying.
SearchResults<Hotel> response = client.Search<Hotel>("luxury");
foreach (SearchResult<Hotel> result in response.GetResults())
{
Hotel doc = result.Document;
Console.WriteLine($"{doc.Id}: {doc.Name}");
}
If you're working with a search index and know the schema, creating C# types is recommended.
SearchOptions
The SearchOptions
provide powerful control over the behavior of our queries.
Let's search for the top 5 luxury hotels with a good rating.
int stars = 4;
SearchOptions options = new SearchOptions
{
// Filter to only ratings greater than or equal our preference
Filter = SearchFilter.Create($"rating ge {stars}"),
Size = 5, // Take only 5 results
OrderBy = new[] { "rating desc" } // Sort by rating from high to low
};
SearchResults<Hotel> response = client.Search<Hotel>("luxury", options);
// ...
Adding documents to your index
You can Upload
, Merge
, MergeOrUpload
, and Delete
multiple documents from
an index in a single batched request. There are
a few special rules for merging
to be aware of.
IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create(
IndexDocumentsAction.Upload(new Hotel { Id = "783", Name = "Upload Inn" }),
IndexDocumentsAction.Merge(new Hotel { Id = "12", Name = "Renovated Ranch" }));
IndexDocumentsOptions options = new IndexDocumentsOptions { ThrowOnAnyError = true };
client.IndexDocuments(batch, options);
The request will succeed even if any of the individual actions fails and
return an IndexDocumentsResult
for inspection. There's also a ThrowOnAnyError
option if you only care about success or failure of the whole batch.
Async APIs
All of the examples so far have been using synchronous APIs, but we provide full
support for async APIs as well. You'll generally just add an Async
suffix to
the name and await
it.
SearchResults<Hotel> response = await client.SearchAsync<Hotel>("luxury");
await foreach (SearchResult<Hotel> result in response.GetResultsAsync())
{
Hotel doc = result.Document;
Console.WriteLine($"{doc.Id}: {doc.Name}");
}
Troubleshooting
Any Azure.Search operation that fails will throw a
RequestFailedException
with
helpful Status
codes. Many of these errors are recoverable.
try
{
return client.GetDocument<Hotel>("12345");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
Console.WriteLine("We couldn't find the hotel you are looking for!");
Console.WriteLine("Please try selecting another.");
}
You can also easily enable console logging if you want to dig deeper into the requests you're making against the service.
Next steps
- Go further with Azure.Search and our samples
- Watch a demo or deep dive video
- Read more about the Azure Cognitive Search service
Contributing
See our Search CONTRIBUTING.md for details on building, testing, and contributing to this library.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit cla.microsoft.com.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.