Neo4j Bolt驱动程序,javascript,处理整数

时间:2017-05-22 15:10:54

标签: javascript neo4j

在Javascript中,Neo4j Bolt驱动程序返回{low:lll,high:hhh}对象代替整数。令人敬畏的64位整数,但它在我简陋的Javascript网络应用程序中引发了一些问题。现在看来我需要遍历所有的前端脚本并检查类型“对象”,无论我从服务器收到日期或号码,然后使用Bolt驱动程序的转换例程(已将驱动程序加载到客户),或建立我自己的。把它推迟了太长时间后,我刚刚从neo4j 2.3升级到3.2并且我在转换为Bolt方面已经深陷其中,但Bolt博士关于整数的那个小附录的全部含义开始陷入困境。

所以Neo4j人:这个博尔特司机值得这么麻烦吗?奇数球的方法是提供稳定的整数还是在某个时刻得到修复 - 例如,通过指示司机如何呈现数字?处理这个我不知道的诀窍吗?我应该退出并返回Akeem的node-neo4j驱动程序吗?

感谢您的任何见解!

2 个答案:

答案 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) {