1

我的索引包含一个 Nest.GeoShape 类型的字段。

----------

问题 #1 —— Kibana 将该字段显示为“indexed = false”,即使它是这样定义的(在创建索引期间使用 .MapFromAttributes())...

    [ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true, IncludeInAll = false)]
    public Nest.GeoShape ElasticShape { get; set; }

这是索引创建,以防出现问题...

    client.CreateIndex(c => c
        .Index(indexName)
        .InitializeUsing(set)
        .AddMapping<ItemSearchable>(m => m
                    .MapFromAttributes()
                    .Properties(props => props
                            .GeoShape(x => x
                                .Name(n => n.ElasticShape)
                                .Tree(GeoTree.Geohash)
                                .TreeLevels(9)
                                .DistanceErrorPercentage(0.025))))

----------

问题 #2——当我进行查询时,返回的结果无法反序列化。

{“无法创建 Nest.GeoShape 类型的实例。类型是接口或抽象类,无法实例化。路径 'hits.hits[0]._source.elasticShape.coordinates',第 10 行,位置 19。”}

我希望这是因为我使用的是 Nest.GeoShape 而不是显式 GeoShape 类型(如 EnvelopeGeoShape),但在我的情况下,每个文档都有不同的形状(5 个可能是圆形、3 个矩形、2 个多边形和 74 个点) .

那么有没有办法可以进一步控制 Json 反序列化来检查类型并显式映射它以生成特定类型?或者(理想情况下)有没有办法让反序列化自动从类型字段中“弄清楚”?

4

1 回答 1

2

好的,这是我发现的反序列化解决方案(问题#2)......

它需要编写一个 CustomCreationConverter 来处理可用于不同 GeoShape 类型的特定字段。以下是积分示例:

public class CustomNestGeoShapeConverter : CustomCreationConverter<Nest.GeoShape>
{
    public override Nest.GeoShape Create(Type objectType)
    {
        return null;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if(token == null) return null;

        switch (token["type"].ToString())
        {
            case "point":
                {
                    var coords = new List<double>();
                    coords.Add(Double.Parse(token["coordinates"][0].ToString()));
                    coords.Add(Double.Parse(token["coordinates"][1].ToString()));
                    return new Nest.PointGeoShape() { Coordinates = coords };
                }
        }

        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后,为了使用这个配置,我在课堂上的字段本身上设置了一个装饰器......

    [JsonConverter(typeof(CustomNestGeoShapeConverter)), ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true, IncludeInAll = false)]
    public Nest.GeoShape ElasticShape { get; set; }

现在这对我来说非常有用,但我仍然需要测试我是否可以搜索形状,即使 Kibana 认为该字段实际上没有被索引(问题 #1)。

于 2015-01-27T16:18:44.287 回答