I have a POCO that has a coordinate field, and the mapping and geodistance search with NEST all works as expected. However, what I'm trying to do with NEST is to also return the distance from the point specified in the GeoDistance query as part of the search results. My research thus far indicates that there are two ways to do this:
- request a sort on the location
- create a script field as part of the query that runs the distance calculation inline
I decided to run with option 2, and here's what some of the code looks like:
public class User
{
public int ID { get; set; }
[GeoPoint]
public Coordinate Location { get; set; }
}
And the query itself:
var results = elasticClient.Search<User>(s => s
.Index("user")
.Query(q => q
.GeoDistance(gd => gd
.Field(f => f.Location)
.Distance(Distance.Miles(distance))
.Location(GeoLocation.TryCreate(data.Latitude, data.Longitude))
) && q
.Exists(e => e
.Field("location")
)
)
.ScriptFields(sf => sf
.ScriptField("distance", sf2 => sf2
.Inline(String.Format("doc['location'].arcDistance({0},{1})", data.Latitude, data.Longitude))
.Lang("painless")
)
)
);
While running this query directly against elasticsearch seems fine, when I do it NEST I have a few issues:
- I cannot access the "distance" script field I defined in my POCO object unless I add it to the definition
- If I create a subclass for the User POCO, ElasticSearch does not deserialize the fields defined in the parent class (which means I only get the Distance script field, not the ID or Location fields, and the Documents array objects are all Null)
- I'm trying to keep a separation between the actual POCO I use for mapping, and the search result object, but I don't know how to mark an attribute / field so that NEST won't map it, but will deserialize the result of the script field into the property
My question is: what is the recommended way to access script fields in NEST? Do I have to forego auto-mapping entirely? Or should I just go for the sort option even though I don't particularly want to sort the results?