-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added .NET client API guide for the Search API.
Signed-off-by: Djcarrillo6 <[email protected]> Fix setup section in guide. Signed-off-by: Djcarrillo6 <[email protected]>
- Loading branch information
1 parent
1b4bb87
commit fc1b6e8
Showing
1 changed file
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
# Search | ||
OpenSearch provides a powerful search API that allows you to search for documents in an index. The search API supports a number of parameters that allow you to customize the search operation. In this guide, we will use the low-level OpenSearch.Net client to explore the search API and its parameters. | ||
|
||
## Setup | ||
Assuming you have OpenSearch running locally on port 9200, you can create a client instance with the following code: | ||
|
||
```csharp | ||
using OpenSearch.Client; | ||
using OpenSearch.Net; | ||
|
||
var node = new Uri("https://localhost:9200"); | ||
var config = new ConnectionSettings(node) | ||
.ServerCertificateValidationCallback(CertificateValidations.AllowAll) | ||
.BasicAuthentication("admin", "admin"); | ||
|
||
var client = new OpenSearchClient(config); | ||
``` | ||
|
||
# Scaffold An Index & Add Documents | ||
```csharp | ||
class Movie | ||
{ | ||
public string Title { get; set; } | ||
public string Director { get; set; } | ||
public int Year { get; set; } | ||
} | ||
|
||
var createIndexResponse = client.Indices.Create("movies", c => c | ||
.Settings(s => s | ||
.NumberOfShards(1) | ||
.NumberOfReplicas(0) | ||
) | ||
.Map(m => m | ||
.Properties(p => p | ||
.Text(t => t | ||
.Name("title") | ||
) | ||
.Text(t => t | ||
.Name("director") | ||
) | ||
.Number(n => n | ||
.Name("year") | ||
) | ||
) | ||
) | ||
); | ||
|
||
// Create 15 movies | ||
var movies = new List<Movie> | ||
{ | ||
new Movie { Title = "The Shawshank Redemption", Director = "Frank Darabont", Year = 1994 }, | ||
new Movie { Title = "The Avengers", Director = "Joss Whedon", Year = 2012 }, | ||
new Movie { Title = "The Dark Knight", Director = "Christopher Nolan", Year = 2008 }, | ||
new Movie { Title = "Pulp Fiction", Director = "Quentin Tarantino", Year = 1994 }, | ||
new Movie { Title = "Fight Club", Director = "David Fincher", Year = 1999 }, | ||
new Movie { Title = "Forrest Gump", Director = "Robert Zemeckis", Year = 1994 }, | ||
new Movie { Title = "Inception", Director = "Christopher Nolan", Year = 2010 }, | ||
new Movie { Title = "The Matrix", Director = "The Wachowski Brothers", Year = 1999 }, | ||
new Movie { Title = "Interstellar", Director = "Christopher Nolan", Year = 2014 }, | ||
new Movie { Title = "The Lord of the Rings: The Fellowship of the Ring", Director = "Peter Jackson", Year = 2001 }, | ||
new Movie { Title = "The Lord of the Rings: The Two Towers", Director = "Peter Jackson", Year = 2002 }, | ||
new Movie { Title = "The Lord of the Rings: The Return of the King", Director = "Peter Jackson", Year = 2003 }, | ||
new Movie { Title = "The Godfather", Director = "Francis Ford Coppola", Year = 1972 }, | ||
new Movie { Title = "The Godfather: Part II", Director = "Francis Ford Coppola", Year = 1974 }, | ||
new Movie { Title = "The Good, the Bad and the Ugly", Director = "Sergio Leone", Year = 1966 } | ||
}; | ||
|
||
// Index the movies | ||
var indexResponse = await client.IndexManyAsync(movies, "movies"); | ||
Console.WriteLine($"Indexed {indexResponse.Items.Count} movies"); // Indexed 15 movies | ||
// Refresh the documents to make them searchable | ||
var refreshResponse = await client.Indices.RefreshAsync("movies"); | ||
``` | ||
|
||
|
||
## Search API | ||
|
||
### Basic Search | ||
The search API allows you to search for documents in an index. The following example searches for ALL documents in the `movies` index: | ||
|
||
```csharp | ||
var searchResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.MatchAll() | ||
) | ||
.TrackTotalHits(true) | ||
); | ||
Console.WriteLine($"Found {searchResponse.Total} movies"); // Found 15 movies | ||
``` | ||
|
||
You can also search for documents that match a specific query. The following example searches for documents that match the query `Avengers`: | ||
```csharp | ||
var searchResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("Avengers") | ||
) | ||
) | ||
.TrackTotalHits(true) | ||
); | ||
``` | ||
|
||
OpenSearch query DSL allows you to specify complex queries. Check out the [OpenSearch query DSL documentation](https://opensearch.org/docs/latest/query-dsl/) for more information. | ||
|
||
|
||
### Basic Pagination | ||
The search API allows you to paginate through the search results. The following example searches for documents that match the query `The Lord of the Rings`, sorted by `year` in in ascending order, and returns the first 2 results after skipping the first 5 results: | ||
|
||
```csharp | ||
var searchResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("The Lord of the Rings") | ||
) | ||
) | ||
.Sort(so => so | ||
.Ascending(f => f.Year) | ||
) | ||
.From(5) | ||
.Size(2) | ||
.TrackTotalHits(true) | ||
); | ||
``` | ||
|
||
### Sorting | ||
With sorting, you can also use the `search_after` parameter to paginate through the search results. Let's say you have already displayed the first page of results, and you want to display the next page. You can use the `search_after` parameter to paginate through the search results. The following example will demonstrate how to get the first 3 pages of results using the search query of the previous example: | ||
|
||
```csharp | ||
var pageOneResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("The Lord of the Rings") | ||
) | ||
) | ||
.Sort(so => so | ||
.Ascending(f => f.Year) | ||
) | ||
.Size(2) | ||
.TrackTotalHits(true) | ||
); | ||
|
||
var pageTwoResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("The Lord of the Rings") | ||
) | ||
) | ||
.Sort(so => so | ||
.Ascending(f => f.Year) | ||
) | ||
.Size(2) | ||
.SearchAfter(pageOneResponse.Hits.Last().Sorts) | ||
.TrackTotalHits(true) | ||
); | ||
|
||
var pageThreeResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("The Lord of the Rings") | ||
) | ||
) | ||
.Sort(so => so | ||
.Ascending(f => f.Year) | ||
) | ||
.Size(2) | ||
.SearchAfter(pageTwoResponse.Hits.Last().Sorts) | ||
.TrackTotalHits(true) | ||
); | ||
``` | ||
|
||
### Pagination with Scroll API | ||
When retrieving large amounts of non-real-time data, you can use the `scroll` parameter to paginate through the search results: | ||
|
||
```csharp | ||
var scrollResponse = await client.SearchAsync<Movie>(s => s | ||
.Index("movies") | ||
.Query(q => q | ||
.Match(m => m | ||
.Field(f => f.Title) | ||
.Query("Lord of the Rings") | ||
) | ||
) | ||
.Sort(so => so | ||
.Ascending(f => f.Year) | ||
) | ||
.Size(2) | ||
.Scroll("1m") | ||
.TrackTotalHits(true) | ||
); | ||
|
||
var scrollResponseTwo = await client.ScrollAsync<Movie>("1m", scrollResponse.ScrollId); | ||
|
||
var scrollResponseThree = await client.ScrollAsync<Movie>("1m", scrollResponseTwo.ScrollId); | ||
``` | ||
|
||
|
||
## Cleanup | ||
```csharp | ||
var deleteIndexResponse = await client.Indices.DeleteAsync("movies"); | ||
``` |