Home > Enterprise >  How to create document with an index in ElasticSearch using NEST library in .NET?
How to create document with an index in ElasticSearch using NEST library in .NET?

Time:12-30

I am trying to use elastic search for the first time in C# and I am trying to create a document which is similar to a row in sql.

For what I understand, index is similar to a table and document is a row. I tried using CreateDocumentAsync method but it does not have any parameter to pass in the index so I am not sure how do I create a document with a particular index. I cannot use default index because our product can have many indices. First I am checking if the index exists and if it does not then it creates the index and then the document

Some code here

public async Task<CreateResponse> CreateDocumentAndIndex<T>(T document, string index) where T : class
{
    CreateResponse response = new(); 
    if (_client.Indices.Exists(index).Exists)
    {
        response = await _client.CreateDocumentAsync<T>(document);
    }
    else
    {
        await _client.IndexAsync(document, idx => idx.Index(index));
        response = await _client.CreateDocumentAsync<T>(document);
    }         
    return response;
}

Now to use this I have a function that calls this method

var response = await elasticSearchClient.CreateDocumentAndIndex<DbContextEventData>(eventData,"test");

But it gives me an error when it is trying to create a document. Is there a way to pass in index when creating a row/document in elastic search

CodePudding user response:

The question is tagged elasticsearch-5, so assuming you're using NEST 5.6.6, the index can be specified at the same time as creating a document

var client = new ElasticClient();

var createResponse = await client.CreateAsync(new { foo = "bar" }, c => c
    .Index("my-index") // index
    .Type("_doc") // document type
    .Id("1") // document id
);

EDIT:

Since you're using Elasticsearch 6.3.0, you must use the latest NEST 6.x client, which at time of writing is 6.8.10. With NEST 6.8.10, a create document API call is as follows

private static void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
    var settings = new ConnectionSettings(pool)
        .DisableDirectStreaming()
        .PrettyJson()
        .DefaultTypeName("_doc") // doc types are gone in future versions, so best to index with this default doc type name
        .OnRequestCompleted(LogToConsole);
        
    var client = new ElasticClient(settings);
    
    if (client.IndexExists("my-index").Exists) 
    {
        client.DeleteIndex("my-index");
    }

    var document = new MyDocument
    {
        Foo = "Bar",
        Baz = 1
    };

    var createResponse = client.Create(document, c => c
        .Index("my-index") // index
        .Id("1") // document id
    );
    
    var returnedDocument = client.Get<MyDocument>("1", g => g.Index("my-index"));
}

public class MyDocument
{
    public string Foo { get; set; }
    
    public int Baz { get; set; }
}

private static void LogToConsole(IApiCallDetails callDetails) 
{
    if (callDetails.RequestBodyInBytes != null)
    {
        var serializer = new JsonSerializer();
        var jObjects = new List<JObject>();
        using (var sr = new StringReader(Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)))
        using (var jsonTextReader = new JsonTextReader(sr))
        {
            jsonTextReader.SupportMultipleContent = true;
            while (jsonTextReader.Read())
                jObjects.Add((JObject)JObject.ReadFrom(jsonTextReader));
        }

        var formatting = jObjects.Count == 1
            ? Newtonsoft.Json.Formatting.Indented
            : Newtonsoft.Json.Formatting.None;
        var json = string.Join("\n", jObjects.Select(j => j.ToString(formatting)));
        Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri} \n{json}");
    }
    else
    {
        Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
    }

    Console.WriteLine();

    if (callDetails.ResponseBodyInBytes != null)
    {
        Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n"  
                 $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n"  
                 $"{new string('-', 30)}\n");
    }
    else
    {
        Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n"  
                 $"{new string('-', 30)}\n");
    }
}

which logs the following to the console

PUT http://localhost:9200/my-index/_doc/1/_create?pretty=true
{
  "foo": "Bar",
  "baz": 1
}

Status: 201
{
  "_index" : "my-index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

------------------------------

GET http://localhost:9200/my-index/_doc/1?pretty=true

Status: 200
{
  "_index" : "my-index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "foo" : "Bar",
    "baz" : 1
  }
}

------------------------------
  • Related