Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 1.x] Add higher-level HTTP DSL methods (#447) #456

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Added support for point-in-time search and associated APIs ([#405](https://github.com/opensearch-project/opensearch-net/pull/405))
- Added support for the component template APIs ([#411](https://github.com/opensearch-project/opensearch-net/pull/411))
- Added support for the composable index template APIs ([#437](https://github.com/opensearch-project/opensearch-net/pull/437))
- Added high-level DSL for raw HTTP methods ([#447](https://github.com/opensearch-project/opensearch-net/pull/447))

### Deprecated
- Deprecated the low-level `IndexTemplateV2` APIs in favour of the new `ComposableIndexTemplate` APIs ([#454](https://github.com/opensearch-project/opensearch-net/pull/454))
Expand Down
9 changes: 9 additions & 0 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,12 @@ var client = new OpenSearchLowLevelClient(config);
```

Note the main difference here is that we are instantiating an `OpenSearchLowLevelClient` rather than `OpenSearchClient`, and `ConnectionConfiguration` instead of `ConnectionSettings`.


## Advanced Features

- [Bulk Requests](guides/bulk.md)
- [Document Lifecycle](guides/document-lifecycle.md)
- [Index Template](guides/index-template.md)
- [Making Raw JSON REST Requests](guides/json.md)
- [Search](guides/search.md)
155 changes: 155 additions & 0 deletions guides/bulk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Bulk

In this guide, you'll learn how to use the OpenSearch .NET Client API to perform bulk operations. You'll learn how to index, update, and delete multiple documents in a single request.

## Setup

First, create a client instance with the following code:

```cs
var nodeAddress = new Uri("http://myserver:9200");
var client = new OpenSearchClient(nodeAddress);
```

Next, create an index named `movies` and another named `books` with the default settings:

```cs
var movies = "movies";
var books = "books";
if (!(await client.Indices.ExistsAsync(movies)).Exists) {
await client.Indices.CreateAsync(movies);
}

if (!(await client.Indices.ExistsAsync(books)).Exists) {
await client.Indices.CreateAsync(books);
}
```

## Bulk API

The `bulk` API action allows you to perform document operations in a single request. The body of the request is an array of objects that contains the bulk operations and the target documents to index, create, update, or delete.

### Indexing multiple documents

The following code creates two documents in the `movies` index and one document in the `books` index:

```cs
var response = await client.BulkAsync(b => b
.Index<object>(i => i
.Index(movies)
.Id(1)
.Document(new { Title = "Beauty and the Beast", Year = 1991 })
)
.Index<object>(i => i
.Index(movies)
.Id(2)
.Document(new { Title = "Beauty and the Beast - Live Action", Year = 2017 })
)
.Index<object>(i => i
.Index(books)
.Id(1)
.Document(new { Title = "The Lion King", Year = 1994 })
));
```

### Creating multiple documents

Similarly, instead of calling the `create` method for each document, you can use the `bulk` API to create multiple documents in a single request. The following code creates three documents in the `movies` index and one in the `books` index:

```cs
var response = await client.BulkAsync(b => b
.Index(movies)
.CreateMany(new[]
{
new { Title = "Beauty and the Beast 2", Year = 2030 },
new { Title = "Beauty and the Beast 3", Year = 2031 },
new { Title = "Beauty and the Beast 4", Year = 2049 }
})
.Create<object>(i => i
.Index(books)
.Document(new { Title = "The Lion King 2", Year = 1998 })
));
```

Note that we specified only the `_index` for the last document in the request body. This is because the `bulk` method accepts an `index` parameter that specifies the default `_index` for all bulk operations in the request body. Moreover, we omit the `_id` for each document and let OpenSearch generate them for us in this example, just like we can with the `create` method.

### Updating multiple documents

```cs
var response = await client.BulkAsync(b => b
.Index(movies)
.Update<object>(i => i
.Id(1)
.Doc(new { Year = 1992 })
)
.Update<object>(i => i
.Id(2)
.Doc(new { Year = 2018 })
));
```

### Deleting multiple documents

```cs
var response = await client.BulkAsync(b => b
.Index(movies)
.DeleteMany<object>(new long[] { 1, 2 }));
```

### Mix and match operations

You can mix and match the different operations in a single request. The following code creates two documents, updates one document, and deletes another document:

```cs
var response = await client.BulkAsync(b => b
.Index(movies)
.CreateMany(new[]
{
new { Title = "Beauty and the Beast 5", Year = 2050 },
new { Title = "Beauty and the Beast 6", Year = 2051 }
})
.Update<object>(i => i
.Id(3)
.Doc(new { Year = 2052 })
)
.Delete<object>(i => i.Id(4)));
```

### Handling errors

The `bulk` API returns an array of responses for each operation in the request body. Each response contains a `status` field that indicates whether the operation was successful or not. If the operation was successful, the `status` field is set to a `2xx` code. Otherwise, the response contains an error message in the `error` field.

The following code shows how to look for errors in the response:

```cs
var response = await client.BulkAsync(b => b
.Index(movies)
.Create<object>(i => i
.Id(1)
.Document(new { Title = "Beauty and the Beast", Year = 1991 })
)
.Create<object>(i => i
.Id(2)
.Document(new { Title = "Beauty and the Beast 2", Year = 2030 })
)
.Create<object>(i => i // document already exists error
.Id(1)
.Document(new { Title = "Beauty and the Beast 3", Year = 2031 })
)
.Create<object>(i => i // document already exists error
.Id(2)
.Document(new { Title = "Beauty and the Beast 4", Year = 2049 })
));

foreach (var item in response.ItemsWithErrors) {
Console.WriteLine(item.Error.Reason);
}
```

## Cleanup

To clean up the resources created in this guide, delete the `movies` and `books` indices:

```cs
await client.Indices.DeleteAsync(new[] { movies, books });
```
Loading
Loading