.NET NEST ElasticClient LowLevel.IndexAsync Creating Document with Empty Fields

Below is a portion of my code, that I've taken from here. I had to make few changes to make it work with the new v6.X of Elasticsearch .NET libraries. I am running this code inside an Azure Function.

It runs without any errors and creates new documents BUT with empty field values. If I take the same JSON payload and PUT in Elasticsearch using Postman, the document gets indexed fine, with all fields populated. Please let me know if I am using the right Elasticsearch API methods, and using them right.

string strJsonMessage = @"
{ 
    message : {
        content: 'Test Message Content'
    }
}";

ConnectionSettings connectionSettings = new ConnectionSettings(new Uri("xxx")).BasicAuthentication("xx", "xx");
ElasticClient client = new ElasticClient(connectionSettings);

JObject msg = JObject.Parse(strJsonMessage);
var result = await client.LowLevel.IndexAsync<BytesResponse>("events-2018.03.27", "event", PostData.Serializable(msg));

if (result.Success)
{
    log.Info("Data successfully sent.");
	log.Verbose(result.Body);
}
else
{
	log.Error("Failed to send data.");
}

****OUTPUT TRACE:****

2018-03-27T18:37:18.961 [Info] Data successfully sent.
2018-03-27T18:37:18.961 [Verbose] {"_index":"events-2018.03.27","_type":"event","_id":"u9HPaGIBBm3ZG7GB5jM_","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":29,"_primary_term":1}

Querying elasticsearch for this document by its ID gives me this:

{
    "_index": "events-2018.03.27",
    "_type": "event",
    "_id": "u9HPaGIBBm3ZG7GB5jM_",
    "_version": 1,
    "found": true,
    "_source": {
        "message": {
            "content": []
        }
    }
}

NEST 6.x ships with an IL merged and renamespaced version of Json.Net, which means ultimately means that it doesn't know how to serialize Newtonsoft.Json.Linq.JObject types in any special way, unlike using Json.NET directly.

You can hook up NEST to use Json.Net as the serializer to handle this by installing the NEST.JsonNetSerializer nuget package and initializing ConnectionSettings as follows

var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings =
    new ConnectionSettings(pool, sourceSerializer: JsonNetSerializer.Default);
var client = new ElasticClient(connectionSettings);

Then JObject will be serialized as expected.

You could avoid the deserialization then reserialization altogether however by passing valid JSON directly to the low level client call.

string json = @"{ 
    ""message"" : {
        ""content"": ""Test Message Content""
    }
}";

var result = client.LowLevel.Index<BytesResponse>("events-2018.03.27", "event", json);

In doing so, you don't need to take the dependency on NEST.JsonNetSerializer nuget package either.

json is implicitly converted to PostData. You can use PostData.String(json); if you'd like to be explicit.

Additionally, if you don't need to response body, you can return VoidResponse.

Thank you very much!! That resolved my issue. I read that json.net has been merged into the latest NEST, couldn't find any samples to properly send JSON in string. Thanks again!!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.