这里的问题是 NEST 6.x+(我将在这些示例中使用 NEST 7.1.0)不知道如何序列化 JObject、JToken 或 JsonElement,或者更准确地说,默认的内部序列化器不知道如何序列化它们。
以JObject为例
public class Log
{
public DateTime timestamp { get; set; }
public JObject data { get; set; }
}
并序列化
var client = new ElasticClient();
var log = new Log
{
timestamp = new DateTime(2019,7,25, 0,0,0, DateTimeKind.Utc),
data = new JObject
{
{ "foo", "bar" },
{ "baz", new JArray(1, 2) },
}
};
client.Index(log, i => i.Index("log"));
产量
POST http://localhost:9200/log/_doc
{"timestamp":"2019-07-25T00:00:00Z","data":[[[]],[[[],[]]]]}
"data" 被序列化为数组数组。 Json.NET 对JObject 进行了特殊处理以将其序列化为对象,但对于任何其他序列化程序,它将使用基于对象类型或对象实现的接口的约定,以及这些可能反映的顺序并下定决心。如果您想在 NEST 6.x 或 7.x 中使用JObject,可以使用NEST.JsonNetSerializer nuget package 和configure it as the serializer for your POCOs。请注意,使用 JsonNetSerializer 会产生一些性能开销,但会牺牲灵活性。
如果你不想走那条路,你可以在 NEST 7.x 中使用DynamicDictionary,这是一个支持动态访问的字典
var client = new ElasticClient();
var log = new Log
{
timestamp = new DateTime(2019,7,25, 0,0,0, DateTimeKind.Utc),
data = new DynamicDictionary
{
{ "foo", new DynamicValue("bar") },
{ "baz", new DynamicValue(new [] { 1, 2 }) },
}
};
client.Index(log, i => i.Index("log"));
序列化为
POST http://localhost:9200/log/_doc?pretty=true
{"timestamp":"2019-07-25T00:00:00Z","data":{"foo":"bar","baz":[1,2]}}