Elasticsearchのクエリに使用する.NETアプリケーションがあります。 Elasticsearchインデックスを正常にクエリしています。結果は次のようになります。
{
"took":31,
"timed_out":false,
"_shards": {
"total":91,
"successful":91,
"skipped":0,
"failed":0
},
"hits":{
"total":1,
"max_score":1.0,
"hits":[
{
"_index":"my-index",
"_type":"doc",
"_id":"TrxrZGYQRaDom5XaZp23",
"_score":1.0,
"_source":{
"my_id":"65a107ed-7325-342d-adab-21fec0a97858",
"Host":"something",
"Zip":"12345"
}
},
]
}
}
現在、このデータはBody
のStringResponse
プロパティを介して取得できます。Elasticsearchから取得しています。実際のレコードを逆シリアル化したい(took
、timed_out
などのプロパティが必要ない、または必要ない)。results
という名前のC#オブジェクトに。これを行うために、私は持っています:
var results = JsonConvert.DeserializeObject<List<Result>>(response.Body);
Result
クラスは次のようになります。
public class Result
{
[JsonProperty(PropertyName = "my_id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "Host")]
public string Host { get; set; }
[JsonProperty(PropertyName = "Zip")]
public string PostalCode { get; set; }
}
これを実行すると、次のエラーが発生します。
現在のJSONオブジェクトを型 'System.Collections.Generic.List`1 [Result]'に逆シリアル化できません。型は正しく逆シリアル化するためにJSON配列を必要とするためです。
エラーは理にかなっていますが、hits
を解析して_source
データを抽出する方法がわかりません。 _source
プロパティには、逆シリアル化するデータが含まれています。他のすべては私が気にしないメタデータです。
これを行う方法はありますか?もしそうなら、どうですか?
Json.Netの LINQ-to-JSON API を使用して、関心のあるノードのみを取得し、それらを結果のリストに変換できます。
var results = JToken.Parse(response.Body)
.SelectTokens("hits.hits[*]._source")
.Select(t => t.ToObject<Result>())
.ToList();
DeserializeObject<T>
T
はJsonと一致しません。 Jsonは{
で始まるため、Tは(IEnumerable
タイプではなく)クラスである必要があります。
外から始めましょう。
{
"took":31,
"timed_out":false,
"_shards": <object>
"hits": <object>
}
そう:
public class SearchResult
{
[JsonProperty("took")]
public int Took { get; set; }
[JsonProperty("timed_out")]
public bool TimedOut { get; set; }
[JsonProperty("_shards")]
public Shards Shards { get; set; }
[JsonProperty("hits")]
public Hits Hits { get; set; }
}
次は_shards
です
"_shards": {
"total":91,
"successful":91,
"skipped":0,
"failed":0
},
そう
public class Shards
{
[JsonProperty("total")]
public int Total { get; set; }
// etc...
}
次にhits
{
"total":1,
"max_score":1.0,
"hits": <IEnumerable because []>
}
そう
public class Hits
{
[JsonProperty("total")]
public int Total { get; set; }
[JsonProperty("max_score")]
public int MaxScore { get; set; }
[JsonProperty("hits")]
public List<Hit> Hits { get; set; }
}
次にHits
リスト:
{
"_index":"my-index",
"_type":"doc",
"_id":"TrxrZGYQRaDom5XaZp23",
"_score":1.0,
"_source": <object>
},
そう
public class Hit
{
[JsonProperty("_index")]
public string Index { get; set; }
// etc
}
そして、必要なものをすべて作成したら、逆シリアル化します。
JsonConvert.DeserializeObject<SearchResult>(json);
次のように、まずジェネリックJToken
またはJObject
に逆シリアル化する必要があります。
var token = JsonConvert.DeserializeObject<JToken>(jsonString);
次に、目的のデータを保持する_ sourceプロパティに移動できます。
var hitsArray = token["hits"]["hits"] as JArray;
var result = hitsArray[0]["_source"].ToObject<Result>();
vSの特別な貼り付け機能によって生成された次の構造を試してください:
public class Rootobject
{
public int took { get; set; }
public bool timed_out { get; set; }
public _Shards _shards { get; set; }
public Hits hits { get; set; }
}
public class _Shards
{
public int total { get; set; }
public int successful { get; set; }
public int skipped { get; set; }
public int failed { get; set; }
}
public class Hits
{
public int total { get; set; }
public float max_score { get; set; }
public Hit[] hits { get; set; }
}
public class Hit
{
public string _index { get; set; }
public string _type { get; set; }
public string _id { get; set; }
public float _score { get; set; }
public _Source _source { get; set; }
}
public class _Source
{
public string my_id { get; set; }
public string Host { get; set; }
public string Zip { get; set; }
}
私は http://json2csharp.com/ を使用してjsonをc#クラスに変換し、私のテストでは http://easyonlineconverter.com/convertersで行われた変換からjson文字列を取得しました/dot-net-string-escape.html
次に、このクラスでコンソールアプリを作成しました。
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string json = "{ \"took\":31, \"timed_out\":false, \"_shards\": { \"total\":91, \"successful\":91, \"skipped\":0, \"failed\":0 }, \"hits\":{ \"total\":1, \"max_score\":1.0, \"hits\":[ { \"_index\":\"my-index\", \"_type\":\"doc\", \"_id\":\"TrxrZGYQRaDom5XaZp23\", \"_score\":1.0, \"_source\":{ \"my_id\":\"65a107ed-7325-342d-adab-21fec0a97858\", \"Host\":\"something\", \"Zip\":\"12345\" } }, ] }}";
RootObject t = JsonConvert.DeserializeObject<RootObject>(json);
}
public class Shards
{
public int total { get; set; }
public int successful { get; set; }
public int skipped { get; set; }
public int failed { get; set; }
}
public class Source
{
public string my_id { get; set; }
public string Host { get; set; }
public string Zip { get; set; }
}
public class Hit
{
public string _index { get; set; }
public string _type { get; set; }
public string _id { get; set; }
public double _score { get; set; }
public Source _source { get; set; }
}
public class Hits
{
public int total { get; set; }
public double max_score { get; set; }
public List<Hit> hits { get; set; }
}
public class RootObject
{
public int took { get; set; }
public bool timed_out { get; set; }
public Shards _shards { get; set; }
public Hits hits { get; set; }
}
}
}
お役に立てれば