如何访问Elasticsearch上使用NEST进行的查询中的脚本字段?

时间:2017-08-10 12:09:46

标签: c# .net elasticsearch nest elasticsearch-painless

我有一个具有坐标字段的POCO,使用NEST进行的映射和地理坐标搜索都按预期工作。但是,我试图用NEST做的也是从GeoDistance查询中指定的点返回距离作为搜索结果的一部分。到目前为止,我的研究表明有两种方法可以做到这一点:

我决定使用选项2运行,这里有一些代码:

public class User
{
    public int ID { get; set; }
    [GeoPoint]
    public Coordinate Location { get; set; }
}

查询本身:

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")
        )
    )                
);

虽然直接针对elasticsearch运行此查询似乎很好,但当我这样做时,我有一些问题:

  • 我无法访问&#34;距离&#34;我在POCO对象中定义的脚本字段,除非我将其添加到定义
  • 如果我为User POCO创建子类,ElasticSearch不会反序列化父类中定义的字段(这意味着我只获取Distance脚本字段,而不是ID或Location字段,而Documents数组对象都是Null )
  • 我试图将用于映射的实际POCO与搜索结果对象分开,但我不知道如何标记属性/字段以便NEST赢得&#39; t映射它,但会将脚本字段的结果反序列化为属性

我的问题是:在NEST中访问脚本字段的推荐方法是什么?我是否必须完全放弃自动映射?或者我应该选择排序选项,即使我不想特别想对结果进行排序?

2 个答案:

答案 0 :(得分:1)

我最终设法接近我想要的东西:

  • 明确告诉我的查询包含_source存储字段 - 似乎不会返回if you use any script fields you need to do this或_source / documents。
  • [ElasticsearchType(Name = "User")]属性添加到我的搜索结果子类
  • 在枚举结果中的Hits时,访问我的脚本字段:

    ((JArray)item.Fields["distance"]).Value<double>(0) / 1609.344 
    

如果有人有更清洁的方法,请告诉我!

答案 1 :(得分:0)

使用 ValueOf 方法有更清晰的方法。 示例

item.Fields.ValueOf<User, string>(p => p.Distance)