Getting started with the high-level .NET client (OpenSearch.Client)

    This getting started guide illustrates how to connect to OpenSearch, index documents, and run queries. For the client source code, see the opensearch-net repo.

    To install OpenSearch.Client, download the OpenSearch.Client NuGet package and add it to your project in an IDE of your choice. In Microsoft Visual Studio, follow the steps below:

    • In the Solution Explorer panel, right-click on your solution or project and select Manage NuGet Packages for Solution.
    • Search for the OpenSearch.Client NuGet package, and select Install.

    Alternatively, you can add OpenSearch.Client to your .csproj file:

    copy

    Example

    The following example illustrates connecting to OpenSearch, indexing documents, and sending queries on the data. It uses the Student class to represent one student, which is equivalent to one document in the index.

    1. {
    2. public int Id { get; init; }
    3. public string FirstName { get; init; }
    4. public string LastName { get; init; }
    5. public int GradYear { get; init; }
    6. public double Gpa { get; init; }
    7. }

    copy

    By default, OpenSearch.Client uses camel case to convert property names to field names.

    Connecting to OpenSearch

    Use the default constructor when creating an OpenSearchClient object to connect to the default OpenSearch host (http://localhost:9200).

    1. var client = new OpenSearchClient();

    copy

    To connect to your OpenSearch cluster through a single node with a known address, specify this address when creating an instance of OpenSearch.Client:

    1. var nodeAddress = new Uri("http://myserver:9200");
    2. var client = new OpenSearchClient(nodeAddress);

    copy

    1. var nodes = new Uri[]
    2. {
    3. new Uri("http://myserver1:9200"),
    4. new Uri("http://myserver2:9200"),
    5. new Uri("http://myserver3:9200")
    6. };
    7. var pool = new StaticConnectionPool(nodes);
    8. var settings = new ConnectionSettings(pool);
    9. var client = new OpenSearchClient(settings);

    copy

    ConnectionConfiguration is used to pass configuration options to the low-level OpenSearch.Net client. ConnectionSettings inherits from ConnectionConfiguration and provides additional configuration options. To set the address of the node and the default index name for requests that don’t specify the index name, create a ConnectionSettings object:

    copy

    Indexing one document

    Create one instance of Student:

    1. var student = new Student { Id = 100, FirstName = "Paulo", LastName = "Santos", Gpa = 3.93, GradYear = 2021 };

    copy

    To index one document, you can use either fluent lambda syntax or object initializer syntax.

    Index this Student into the students index using fluent lambda syntax:

    1. var response = client.Index(student, i => i.Index("students"));

    copy

    Index this Student into the students index using object initializer syntax:

    1. var response = client.Index(new IndexRequest<Student>(student, "students"));

    copy

    Indexing many documents

    You can index many documents from a collection at the same time by using the OpenSearch.Client’s IndexMany method:

    1. var studentArray = new Student[]
    2. {
    3. new() {Id = 200, FirstName = "Shirley", LastName = "Rodriguez", Gpa = 3.91, GradYear = 2019},
    4. new() {Id = 300, FirstName = "Nikki", LastName = "Wolf", Gpa = 3.87, GradYear = 2020}
    5. };
    6. var manyResponse = client.IndexMany(studentArray, "students");

    To search for a student indexed above, you want to construct a query that is analogous to the following Query DSL query:

    The query above is a shorthand version of the following explicit query:

    1. GET students/_search
    2. {
    3. "query" : {
    4. "match": {
    5. "lastName": {
    6. "query": "Santos"
    7. }
    8. }
    9. }
    10. }

    In OpenSearch.Client, this query looks like this:

    1. var searchResponse = client.Search<Student>(s => s
    2. .Index("students")
    3. .Match(m => m
    4. .Field(fld => fld.LastName)

    copy

    You can print out the results by accessing the documents in the response:

    1. if (searchResponse.IsValid)
    2. {
    3. foreach (var s in searchResponse.Documents)
    4. {
    5. Console.WriteLine($"{s.Id} {s.LastName} {s.FirstName} {s.Gpa} {s.GradYear}");
    6. }
    7. }

    copy

    The response contains one document, which corresponds to the correct student:

    100 Santos Paulo 3.93 2021

    Using OpenSearch.Client methods asynchronously

    For applications that require asynchronous code, all method calls in OpenSearch.Client have asynchronous counterparts:

    1. // synchronous method
    2. var response = client.Index(student, i => i.Index("students"));
    3. // asynchronous method
    4. var response = await client.IndexAsync(student, i => i.Index("students"));

    Falling back on the low-level OpenSearch.Net client

    OpenSearch.Client exposes the low-level the OpenSearch.Net client you can use if anything is missing:

    copy

    1. using OpenSearch.Client;
    2. using OpenSearch.Net;
    3. namespace NetClientProgram;
    4. internal class Program
    5. {
    6. private static IOpenSearchClient osClient = new OpenSearchClient();
    7. public static void Main(string[] args)
    8. {
    9. Console.WriteLine("Indexing one student......");
    10. var student = new Student { Id = 100,
    11. FirstName = "Paulo",
    12. LastName = "Santos",
    13. Gpa = 3.93,
    14. GradYear = 2021 };
    15. var response = osClient.Index(student, i => i.Index("students"));
    16. Console.WriteLine(response.IsValid ? "Response received" : "Error");
    17. Console.WriteLine("Searching for one student......");
    18. SearchForOneStudent();
    19. Console.WriteLine("Searching using low-level client......");
    20. SearchLowLevel();
    21. Console.WriteLine("Indexing an array of Student objects......");
    22. var studentArray = new Student[]
    23. {
    24. new() { Id = 200,
    25. FirstName = "Shirley",
    26. LastName = "Rodriguez",
    27. Gpa = 3.91,
    28. GradYear = 2019},
    29. new() { Id = 300,
    30. FirstName = "Nikki",
    31. LastName = "Wolf",
    32. Gpa = 3.87,
    33. GradYear = 2020}
    34. };
    35. }
    36. private static void SearchForOneStudent()
    37. {
    38. var searchResponse = osClient.Search<Student>(s => s
    39. .Index("students")
    40. .Query(q => q
    41. .Match(m => m
    42. .Field(fld => fld.LastName)
    43. .Query("Santos"))));
    44. PrintResponse(searchResponse);
    45. }
    46. private static void SearchLowLevel()
    47. {
    48. // Search for the student using the low-level client
    49. var lowLevelClient = osClient.LowLevel;
    50. var searchResponseLow = lowLevelClient.Search<SearchResponse<Student>>
    51. ("students",
    52. PostData.Serializable(
    53. new
    54. {
    55. query = new
    56. {
    57. match = new
    58. {
    59. lastName = new
    60. {
    61. query = "Santos"
    62. }
    63. }
    64. }
    65. }));
    66. PrintResponse(searchResponseLow);
    67. }
    68. private static void PrintResponse(ISearchResponse<Student> response)
    69. {
    70. if (response.IsValid)
    71. {
    72. foreach (var s in response.Documents)
    73. {
    74. Console.WriteLine($"{s.Id} {s.LastName} " +
    75. $"{s.FirstName} {s.Gpa} {s.GradYear}");
    76. }
    77. }
    78. else
    79. {
    80. Console.WriteLine("Student not found.");
    81. }
    82. }

    copy