1

私のインデックスには、Nest.GeoShape タイプのフィールドが含まれています。

----------

問題 #1 -- このように定義されていても (インデックス作成時に .MapFromAttributes() を使用して)、Kibana はそのフィールドを「indexed = false」と表示します...

    [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."}

明示的な GeoShape タイプ (EnvelopeGeoShape など) ではなく、Nest.GeoShape を使用しているためだと思いますが、私の場合、各ドキュメントは異なる形状になります (5 つは円、3 つの長方形、2 つのポリゴン、および 74 ポイント)。 .

Json Deserialization をさらに制御して型をチェックし、明示的にマップして特定の型を生成する方法はありますか? または(理想的には)型フィールドから自動的に逆シリアル化に「それを理解させる」方法はありますか?

4

1 に答える 1

2

さて、デシリアライゼーション(問題#2)の解決策として私が見つけたものは次のとおりです...

さまざまな GeoShape タイプで使用できる特定のフィールドを処理するには、CustomCreationConverter を記述する必要があります。ポイントのサンプルは次のとおりです。

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 に答える