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)不知道如何序列化 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
进行特殊处理以将其序列化为对象,但对于任何其他序列化程序,它将使用基于对象类型或对象实现的接口的约定,以及这些序列化的顺序可能会反映过来并确定。如果您想将 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]}}
我在 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)不知道如何序列化 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
进行特殊处理以将其序列化为对象,但对于任何其他序列化程序,它将使用基于对象类型或对象实现的接口的约定,以及这些序列化的顺序可能会反映过来并确定。如果您想将 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]}}