2

I have a lot of different collections of values I generate at runtime and want to send them to ElasticSearch. I can represent them as List<object> or if really doesn't work any other way, as List<string>. But I can't find any example how to do that. Here is an example of the code which doesn't work. There is probably a lot wrong with it, so any additional pointers are highly appreciated.

  var client = new ElasticClient(new Uri("http://localhost:9200"));
            client.CreateIndex("testentry");
            var values = new List<object> {"StringValue", 123, DateTime.Now};
            var indexResponse = client.Index(values, descriptor => descriptor.Index("testentry"));
            Console.WriteLine(indexResponse.DebugInformation);

Which results in:

Invalid NEST response built from a unsuccessful low level call on POST: /testentry/list%601
# Audit trail of this API call:
 - [1] BadResponse: Node: http://localhost:9200/ Took: 00:00:00.0600035
# ServerError: ServerError: 400Type: mapper_parsing_exception Reason: "failed to parse" CausedBy: "Type: not_x_content_exception Reason: "Compressor detection can only be called on some xcontent bytes or compressed xcontent bytes""

and

[2016-09-17 14:16:20,955][DEBUG][action.index             ] [Gin Genie] failed to execute [index {[t
estentry][list`1][AVc4E3HaPglqpoLcosDo], source[_na_]}] on [[testentry][1]]
MapperParsingException[failed to parse]; nested: NotXContentException[Compressor detection can only
be called on some xcontent bytes or compressed xcontent bytes];
        at org.elasticsearch.index.mapper.DocumentParser.parseDocument(DocumentParser.java:156)

I'm using Elasticsearch.Net 2.4.3 and NEST 2.4.3.

2 Answers 2

4

In addition to Henrik's answer, you could also index values in a Dictionary<string, object>

public class MyType
{
    public MyType()
    {
        Values = new Dictionary<string, object>();
    }

    public Dictionary<string, object> Values { get; private set; }
}

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var connectionSettings = new ConnectionSettings(pool);

    var client = new ElasticClient(connectionSettings);

    var myType = new MyType
    {
        Values =
        {
            { "value1", "StringValue" },
            { "value2", 123 },
            { "value3", DateTime.Now },
        }
    };

    client.Index(myType, i => i.Index("index-name"));
}

The Dictionary<string,object> will be serialized to a json object with property names to match the dictionary keys

{
  "values": {
    "value1": "StringValue",
    "value2": 123,
    "value3": "2016-09-18T18:41:48.7344837+10:00"
  }
}

Within Elasticsearch, the mapping will be inferred as an object type.

Sign up to request clarification or add additional context in comments.

Comments

3

Arrays with a mixture of datatypes are not supported.

You could convert all of the values to strings:

client.CreateIndex("testentry");
var values = new List<string> { "StringValue", "123", DateTime.Now.ToString() };
var indexResponse = client.Index(new { Values = values}, descriptor => descriptor.Index("testentry").Type("test"));

Or specify the fields that the values should be indexed to:

client.CreateIndex("testentry");
var values = new { Field1 = "StringValue", Field2 = 123, Field3 = DateTime.Now };
var indexResponse = client.Index(values, descriptor => descriptor.Index("testentry").Type("test"));

Consider specifying the type of the document with the IndexDescriptor or create a class for the document.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.