Skip to content

Commit

Permalink
Added .NET client API guide for the Search API.
Browse files Browse the repository at this point in the history
Signed-off-by: Djcarrillo6 <[email protected]>

Fix setup section in guide.

Signed-off-by: Djcarrillo6 <[email protected]>
  • Loading branch information
Djcarrillo6 committed Oct 12, 2023
1 parent 1b4bb87 commit fc1b6e8
Showing 1 changed file with 212 additions and 0 deletions.
212 changes: 212 additions & 0 deletions guides/search.md
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");
```

0 comments on commit fc1b6e8

Please sign in to comment.