NEST (C#) Index list of custom, location-like objects - how to map it to index properly?

I have a simple Poco

class Product
{
...
public List Adrresses {get; set;}
}

class GeoItem
{
public string Address {get; set;}
public double Latititude {get; set;}
public double Longitude {get; set;}
....
}

So, could you please provide me an example of how should I write fluent mapping for the Product and could I map GeoPoint from GeoItem directly, or I need to somehow convert GeoItem to GeoLocation object somehow with decorator for instance?

Take a look at the fluent mapping documentation as I think it'll help to see what mapping is generated for different fluent API mappings.

You probably want to map at least the Latitude and a Longitude of GeoItem to GeoLocation as NEST understands how to serialize GeoLocation when making the indexing request to Elasticsearch, and understands to automap as geo_point when creating a mapping from the type.

Here's an example

public class Product
{
    public List<GeoItem> Addresses {get;set;}
}

public class GeoItem
{
    public string Address { get; set; }
    public GeoLocation LatLon {get;set;}
}

var client = new ElasticClient(settings);

var indexResponse = client.CreateIndex("my_index", c => c
    .Mappings(m => m
        .Map<Product>(mm => mm
            .AutoMap()
            .Properties(p => p
                .Nested<GeoItem>(n => n
                    .Name(nn => nn.Addresses)
                    .AutoMap()
                )
            )
        )
    )
);

generates the following create index request

PUT http://localhost:9200/my_index
{
  "mappings": {
    "product": {
      "properties": {
        "addresses": {
          "type": "nested",
          "properties": {
            "address": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "latLon": {
              "type": "geo_point"
            }
          }
        }
      }
    }
  }
}

@forloop The problem is that I use GeoItem in other places of my code and it's already settled with current structure, so I can't change it to support elastic GeoLocation directly. Is there a way to somehow set dynamic conversion from GeoItem to GeoLocation during the mapping phase (like in automapper for instance) or I need to create separate model?

You could write your own Json.NET JsonConverter for GeoItem that serializes it to the format expected by Elasticsearch, then use the Nest.JsonNetSerializer nuget package and hook up the JsonNetSerializer as the serializer for the client to use

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

Alternatively, you could use specific types to represent the documents in Elasticsearch and use GeoLocation, then map your domain objects to these POCOs with something like AutoMapper.

ok, I decide to proceed with special elasticmodels since there is seems like similar problem with other elastic specific fields like DoubleRange for example. But thanks a lot for your advice

That's what I would recommend, since it'll allow you to take advantage of Nest specific types on your models

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