在Javascript中,Neo4j Bolt驱动程序返回{low:lll,high:hhh}对象代替整数。令人敬畏的64位整数,但它在我简陋的Javascript网络应用程序中引发了一些问题。现在看来我需要遍历所有的前端脚本并检查类型“对象”,无论我从服务器收到日期或号码,然后使用Bolt驱动程序的转换例程(已将驱动程序加载到客户),或建立我自己的。把它推迟了太长时间后,我刚刚从neo4j 2.3升级到3.2并且我在转换为Bolt方面已经深陷其中,但Bolt博士关于整数的那个小附录的全部含义开始陷入困境。
所以Neo4j人:这个博尔特司机值得这么麻烦吗?奇数球的方法是提供稳定的整数还是在某个时刻得到修复 - 例如,通过指示司机如何呈现数字?处理这个我不知道的诀窍吗?我应该退出并返回Akeem的node-neo4j驱动程序吗?
感谢您的任何见解!
答案 0 :(得分:1)
Neo4j显然正朝着使用BOLT协议和相关驱动程序进行与数据库的所有交互。协议本身最多返回64位整数(https://boltprotocol.org/v1/#ints)。
但是,Javascript只有一个Number类型,它是浮点数,并且只能精确地将整数表示为53位(http://ecma262-5.com/ELS5_HTML.htm#Section_8.5)。
要使Javascript代码能够准确处理大于53位的整数,需要将这些数字编码为不同的类型。 Neo4j Javascript驱动程序为此目的引入了Integer对象(https://neo4j.com/docs/api/javascript-driver/current/class/src/v1/integer.js~Integer.html)。幸运的是,该对象包含许多实用方法,包括toInt()
和toNumber()
,用于转换回常规Javascript类型(如果整数大于2 ^ 53,则可以检查精度损失,可以检查使用inSafeRange()
)。
答案 1 :(得分:0)
回答我的问题:
a)使用套接字和自定义协议将螺栓驱动器与neo4j紧密耦合(感谢Chris指针);因此,我认为值得解决;但是,有一些问题,因为事实上你必须在每个点添加转换例程,在所有服务器和客户端脚本中从db返回一个整数;另外,如果你不使用64位整数,那么驱动程序会将所有的int都转换为对象,然后你必须将它们全部转换回来,所以它有点额外的重量。服务器。
b)我提出了neo4j-driver devs的一个问题,请求运行'运行'导致驱动程序返回最多2 ^ 53的Javascript数字或在越界整数上引发异常的方法;这将使升级更容易,让服务器在我的情况下运行更清洁;此请求正在等待处理;
c)至于捷径,我使用了以下内容;希望他们帮助别人:
1)首先,为了避免必须将neoj4-driver /库加载到客户端,我复制了驱动程序的转换例程。我将以下2行添加到客户端脚本中;然后我可以调用 bolt_num(n)来转换为数字:
const TWO_PWR_32_DBL = (1 << 16) * (1 << 16);
const bolt_num = function(n){ return typeof n == 'object'? n.hasOwnProperty('low')? n.high * TWO_PWR_32_DBL + (n.low >>> 0) : n : n; }
2)在更改了50个左右的错误之后,我查看了修补驱动程序以返回js数字。下面的临时修复并没有捕获越界的内容,但正如我所说,我不需要这样做。更改适用于neo4j-javascript-driver(v1.4)在一个文件中: node_modules / neo4j-driver / internal / packstream.js ,从第400行左右开始。我的5个替换行被注释为 // new ;他们取代的行被注释掉了。在我的应用程序代码中,我已经做出的更改继续有效 - neo4j-driver转换接受普通整数。因此,这使我可以更快地启动和运行,按照我自己的步调添加数字转换 - 除非我决定只使用修改后的驱动程序,以免减慢我的节点服务器速度。
key: "unpack",
value: function unpack(buffer) {
var marker = buffer.readUInt8();
if (marker == NULL) {
return null;
} else if (marker == TRUE) {
return true;
} else if (marker == FALSE) {
return false;
} else if (marker == FLOAT_64) {
return buffer.readFloat64();
} else if (marker >= 0 && marker < 128) {
return marker; // new
//return (0, _integer.int)(marker);
} else if (marker >= 240 && marker < 256) {
return marker-256; // new
//return (0, _integer.int)(marker - 256);
} else if (marker == INT_8) {
return buffer.readInt8(); // new
//return (0, _integer.int)(buffer.readInt8());
} else if (marker == INT_16) {
return buffer.readInt16(); // new
//return (0, _integer.int)(buffer.readInt16());
} else if (marker == INT_32) {
return buffer.readInt32(); // new
//var b = buffer.readInt32();
//return (0, _integer.int)(b);
} else if (marker == INT_64) {
var high = buffer.readInt32();
var low = buffer.readInt32();
var TWO_PWR_32_DBL = (1 << 16) * (1 << 16); // new
return high * TWO_PWR_32_DBL + (low >>> 0); // new
//return new _integer2.default(low, high);
} else if (marker == STRING_8) {