Skip to content

Commit

Permalink
Added .NET client API guide for the Search API. (opensearch-project#394)
Browse files Browse the repository at this point in the history
Fix setup section in guide.



Minor updates to search.md



Added requested changes to search.md



Added requested changes to search.md #2



Added requested changes to search.md #3

Signed-off-by: Djcarrillo6 <[email protected]>
  • Loading branch information
Djcarrillo6 authored Oct 18, 2023
1 parent ee61ac4 commit b014ff4
Showing 1 changed file with 148 additions and 0 deletions.
148 changes: 148 additions & 0 deletions guides/search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# 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 explore the search API and its parameters.

## Setup
Let's start by creating an index and adding some documents to it:

```csharp
using OpenSearch.Client;
using OpenSearch.Net;

var node = new Uri("https://localhost:9200");
var config = new ConnectionSettings(node)
.ThrowExceptions()
.ServerCertificateValidationCallback(CertificateValidations.AllowAll)
.BasicAuthentication("admin", "admin");
var client = new OpenSearchClient(config);

class Movie
{
public string Title { get; set; }
public string Director { get; set; }
public int Year { get; set; }
public override string ToString()
{
return $"{nameof(Title)}: {Title}, {nameof(Director)}: {Director}, {nameof(Year)}: {Year}";
}
}

await client.Indices.CreateAsync("movies", c => c
.Settings(s => s
.NumberOfShards(1)
.NumberOfReplicas(0)
)
.Map<Movie>(m => m
.Properties(p => p
.Text(t => t
.Name(o => o.Title))
.Text(t => t
.Name(o => o.Director))
.Number(n => n
.Name(o => o.Year)
.Type(NumberType.Integer)))));

var movies = new List<Movie>
{
new Movie { Title = "The Godfather", Director = "Francis Ford Coppola", Year = 1972 },
new Movie { Title = "The Shawshank Redemption", Director = "Frank Darabont", Year = 1994 },
};

for (var i = 0; i < 10; ++i)
movies.Add(new Movie { Title = "The Dark Knight " + i, Director = "Christopher Nolan", Year = 2008 + i });

// Index the movies
var indexResponse = await client.BulkAsync(b => b
.Index("movies")
.IndexMany(movies)
.Refresh(Refresh.WaitFor));
Console.WriteLine($"Indexed {indexResponse.Items.Count} movies"); // Indexed 12 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()));
Console.WriteLine(string.Join('\n', searchResponse.Documents));
```

You can also search for documents that match a specific query. The following example searches for documents that match the query `dark knight`:
```csharp
var searchResponse = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(q => q
.Match(m => m
.Field(f => f.Title)
.Query("dark knight"))));
Console.WriteLine(string.Join('\n', searchResponse.Documents));
```

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 `dark knight`, sorted by `year` in in ascending order, and returns the first 2 results after skipping the first 5 results:

```csharp
var query = Query<Movie>.Match(m => m
.Field(f => f.Title)
.Query("dark knight"));
var sort = new SortDescriptor<Movie>()
.Ascending(f => f.Year);
var searchResponse = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(_ => query)
.Sort(_ => sort)
.From(5)
.Size(2));
Console.WriteLine(string.Join('\n', searchResponse.Documents));
```

With sorting, you can also use the `SearchAfter` 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 `SearchAfter` 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 page1 = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(_ => query)
.Sort(_ => sort)
.Size(2));
var page2 = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(_ => query)
.Sort(_ => sort)
.Size(2)
.SearchAfter(page1.Hits.Last().Sorts));
var page3 = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(_ => query)
.Sort(_ => sort)
.Size(2)
.SearchAfter(page2.Hits.Last().Sorts));
Console.WriteLine(string.Join('\n', page3.Documents));
```

### 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 page1 = await client.SearchAsync<Movie>(s => s
.Index("movies")
.Query(_ => query)
.Sort(_ => sort)
.Size(2)
.Scroll("1m"));
var page2 = await client.ScrollAsync<Movie>("1m", page1.ScrollId);
var page3 = await client.ScrollAsync<Movie>("1m", page2.ScrollId);
Console.WriteLine(string.Join('\n', page3.Documents));
```


## Cleanup
```csharp
await client.Indices.DeleteAsync("movies");
```

0 comments on commit b014ff4

Please sign in to comment.