NEST dotnet 核心弹性没有正确索引

NEST dotnet core elastic not properly indexing

我在 dot net core (v3 preview6) 中遇到 NEST 和弹性记录器的问题。

我有一个日志 class 注意数据属性,我希望它能接受我扔给它的任何 json,从 API/route 的角度来看它工作正常,我可以填充属性,但是它没有通过 NEST 正确地传输到弹性搜索。我试过将其作为 JObject JToken 和 System.Text.Json.JsonElement:

发送
    public class Log
    {

        public System.DateTime timestamp { get; set; }
        public System.Text.Json.JsonElement data {get; set;}
    }

然后我就这样使用我的 Elastic 客户端:

var response = client.Index(log, idx => idx.Index("log"));

无论类型如何,我都无法在弹性搜索中将我的动态 json 转换为 json。我错过了什么?

这里的问题是 NEST 6.x+(我将在这些示例中使用 NEST 7.1.0)不知道如何序列化 JObjectJTokenJsonElement,或者更准确地说,默认的内部序列化程序不知道如何序列化它们。

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 进行特殊处理以将其序列化为对象,但对于任何其他序列化程序,它将使用基于对象类型或对象实现的接口的约定,以及这些序列化的顺序可能会反映过来并确定。如果您想将 JObject 与 NEST 6.x 或 7.x 一起使用,您可以使用 NEST.JsonNetSerializer nuget package and 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]}}