Search code examples
c#elasticsearchnest

Is is possible to flatten parts of object when auto mapping


I'm new to using Elasticsearch and I am using search on a services where part of the result I get back is formatted like this(names translated from other language):

accounting: {
    properties: {
        accountingInterval: {
            properties: {
                endDate: {
                    type: "date",
                    format: "dateOptionalTime"
                },
                startDate: {
                    type: "date",
                    format: "dateOptionalTime"
                }
            }
        }
    }
}

I can auto map it to object like this without a problem:

class MyBaseObject
{
    public Accounting Accounting { get; set; }
    //...some other values on base object
}

class Accounting
{
    public AccountingInterval AccountingInterval { get; set; }
}

class AccountingInterval
{
    [Date(Format = "dateOptionalTime")]
    public DateTime? StartDate { get; set; }
    [Date(Format = "dateOptionalTime")]
    public DateTime? EndDate { get; set; }
}

Is there an way to get it to map to a simple object like this:

class MyBaseObject
{
    [Date(Format = "dateOptionalTime")]
    public DateTime? AccountingStartDate { get; set; }
    [Date(Format = "dateOptionalTime")]
    public DateTime? AccountingEndDate { get; set; }
    //...some other values on base object
}

I tried setting the name attribute but it did not seem to work

class MyBaseObject
{
    [Date(Name ="accounting.accountingInterval.startDate", Format = "dateOptionalTime")]
    public DateTime? AccountingStartDate { get; set; }
    [Date(Name ="accounting.accountingInterval.endDate", Format = "dateOptionalTime")]
    public DateTime? AccountingEndDate { get; set; }
    //...some other values on base object
}

Solution

  • As panchicore said in the comments, it would be possible to perform this flattening at index time with Ingest node and pipelines, and the type mapping in the index would reflect this structure.

    If you're not responsible for indexing, then this is trickier to do. The mapping in NEST is used for both input to and output of documents from Elasticsearch. It'd be possible to control how JSON is deserialized to MyBaseObject by hooking up the Nest.JsonSerializer nuget package, and using Json.NET as the serializer for the client, and defining a custom JsonConverter for the MyBaseObject type. If you'd only like to do it for type aesthetics though, the effort is probably more than the value!