Gremlin.NET 反序列化数字 属性
Gremlin.NET deserialize number property
我有一个创建顶点和边“已创建”的查询。边缘有一个 属性 “on”,它是 unix 日期时间长度。当我在 Azure Cosmos DB 终端中使用以下段执行查询时,它按预期工作 - 返回一个带有数字“On”属性 的对象。
.project('Id', 'CreatedOn')
.by('id')
.by(
select('createdEdge')
.by('on')
)
当我使用 Gremlin.NET 从我的应用程序代码执行此查询时,它失败并显示错误:
JSON type not supported.
我看到 in the source code Gremlin.NET 的反序列化逻辑似乎不处理任何数字类型。真的是这样吗?没有办法使用long,float,int属性类型吗?
Gremlin.NET does not seem to handle any number types. Is this really the case? Is there no way to use long, float, int property types?
Gremlin.NET 当然支持数字类型的序列化。然而,TinkerPop 有自己的序列化格式,其中之一是基于 JSON 的 GraphSON 格式,Cosmos DB 也支持该格式。
GraphSON 基本上将所有内容序列化为 JSON 中的对象,该对象由类型键和值组成。所以,一个整数将像这样被序列化:
{
"@type" : "g:Int32",
"@value" : 100
}
此类型标识符是随 GraphSON 2 添加的,仅用于 GraphSON 3 中的所有类型。GraphSON 2 仍然序列化了一些没有此类型标识符的类型。 GraphSON 2 spec 是这样描述的:
With GraphSON 2.0, there are essentially two type formats:
A non-typed value which is assumed the type implied by JSON. These non-types are limited to String, Boolean, Map and Collection.
All other values are typed by way of a "complex object" that defines a @typeId and @value.
如您所见,数值类型未列为没有类型标识符的类型。
The Cosmos DB docs mention that they only support GraphSON 2,但看起来他们序列化了没有此类型标识符的数字类型。这曾经与 Gremlin.NET 版本 < 3.5.0 一起使用,因为它仍然具有反序列化没有类型标识符的数字类型的逻辑。这只是 GraphSON 1 格式的遗留问题,没有这些类型标识符。
Gremlin.NET 3.5.0 对 JSON 序列化进行了重大更改,主要是由于从 Newtonsoft.JSON 到 System.Text.Json 的切换,并且此逻辑被删除为该更改的一部分。
因此,看起来您需要继续使用 Gremlin.NET 3.4,直到 Cosmos DB 修复它们的序列化。
请注意这里有一个 work-around:https://www.mail-archive.com/dev@tinkerpop.apache.org/msg22532.html
简而言之,您可以创建一个派生自 GraphSON2Reader 的自定义 reader:
public class CustomGraphSON2Reader : GraphSON2Reader
{
public override dynamic ToObject(JsonElement graphSon) =>
graphSon.ValueKind switch
{
// numbers
JsonValueKind.Number when graphSon.TryGetInt32(out var intValue) => intValue,
JsonValueKind.Number when graphSon.TryGetInt64(out var longValue) => longValue,
JsonValueKind.Number when graphSon.TryGetDecimal(out var decimalValue) => decimalValue,
_ => base.ToObject(graphSon)
};
}
然后将其传递给您的客户端:
var client = new GremlinClient(server, new GraphSON2MessageSerializer(new CustomGraphSON2Reader()));
我有一个创建顶点和边“已创建”的查询。边缘有一个 属性 “on”,它是 unix 日期时间长度。当我在 Azure Cosmos DB 终端中使用以下段执行查询时,它按预期工作 - 返回一个带有数字“On”属性 的对象。
.project('Id', 'CreatedOn')
.by('id')
.by(
select('createdEdge')
.by('on')
)
当我使用 Gremlin.NET 从我的应用程序代码执行此查询时,它失败并显示错误:
JSON type not supported.
我看到 in the source code Gremlin.NET 的反序列化逻辑似乎不处理任何数字类型。真的是这样吗?没有办法使用long,float,int属性类型吗?
Gremlin.NET does not seem to handle any number types. Is this really the case? Is there no way to use long, float, int property types?
Gremlin.NET 当然支持数字类型的序列化。然而,TinkerPop 有自己的序列化格式,其中之一是基于 JSON 的 GraphSON 格式,Cosmos DB 也支持该格式。 GraphSON 基本上将所有内容序列化为 JSON 中的对象,该对象由类型键和值组成。所以,一个整数将像这样被序列化:
{
"@type" : "g:Int32",
"@value" : 100
}
此类型标识符是随 GraphSON 2 添加的,仅用于 GraphSON 3 中的所有类型。GraphSON 2 仍然序列化了一些没有此类型标识符的类型。 GraphSON 2 spec 是这样描述的:
With GraphSON 2.0, there are essentially two type formats:
A non-typed value which is assumed the type implied by JSON. These non-types are limited to String, Boolean, Map and Collection.
All other values are typed by way of a "complex object" that defines a @typeId and @value.
如您所见,数值类型未列为没有类型标识符的类型。
The Cosmos DB docs mention that they only support GraphSON 2,但看起来他们序列化了没有此类型标识符的数字类型。这曾经与 Gremlin.NET 版本 < 3.5.0 一起使用,因为它仍然具有反序列化没有类型标识符的数字类型的逻辑。这只是 GraphSON 1 格式的遗留问题,没有这些类型标识符。
Gremlin.NET 3.5.0 对 JSON 序列化进行了重大更改,主要是由于从 Newtonsoft.JSON 到 System.Text.Json 的切换,并且此逻辑被删除为该更改的一部分。 因此,看起来您需要继续使用 Gremlin.NET 3.4,直到 Cosmos DB 修复它们的序列化。
请注意这里有一个 work-around:https://www.mail-archive.com/dev@tinkerpop.apache.org/msg22532.html
简而言之,您可以创建一个派生自 GraphSON2Reader 的自定义 reader:
public class CustomGraphSON2Reader : GraphSON2Reader
{
public override dynamic ToObject(JsonElement graphSon) =>
graphSon.ValueKind switch
{
// numbers
JsonValueKind.Number when graphSon.TryGetInt32(out var intValue) => intValue,
JsonValueKind.Number when graphSon.TryGetInt64(out var longValue) => longValue,
JsonValueKind.Number when graphSon.TryGetDecimal(out var decimalValue) => decimalValue,
_ => base.ToObject(graphSon)
};
}
然后将其传递给您的客户端:
var client = new GremlinClient(server, new GraphSON2MessageSerializer(new CustomGraphSON2Reader()));