【问题标题】:pymongo 64bit unsigned integerpymongo 64位无符号整数
【发布时间】:2012-01-11 19:37:51
【问题描述】:

我正在尝试使用 pymongo 在 mongodb 中插入一个 64 位无符号整数。该整数是 CRC64 算法的输出。我试图关注:

long(crc64(unicode(kw).encode('unicode-escape'))))

如果我将它插入到 mongodb 中,它开始抱怨 mongodb 只支持 64 位整数。接下来我尝试将其转换为有符号的 64 位 int,如下所示:

ctypes.c_int64(crc64(unicode(kw).encode('unicode-escape')))).value

哪种有效,mongodb 不再抱怨我的 int 的大小,但是当我查看 mongodb 中的数据时,我得到了这个:

{
    "_id" : {
        "floatApprox" : -5307924876159732000,
        "top" : 3059119730,
        "bottom" : 2651469802 },
    "keyword" : "redacted",
    "normal_hash" : { 
        "floatApprox" : -671156942315906300,
        "top" : 4138701393,
        "bottom" : 549001936
    } 
}

这里发生了什么?有什么方法可以将 64 位 int 作为一个 int 放入 db 中(真的不在乎它是带符号的还是无符号的。)

【问题讨论】:

  • 你是在 32 位还是 64 位机器上运行 mongo?
  • 你试过把它编码成二进制吗?

标签: python mongodb unsigned pymongo


【解决方案1】:

MongoDB 使用 BSON 来存储数据,并且 BSON 规范说 64 位整数是有符号的。

64 位机器上的示例会话,64 位 mongo v2.0.1,python 2.6.5:

>>> num = long(9007199254740992)
>>> num
9007199254740992L
>>> bson = BSON.encode({"crc64":num})
>>> bson
'\x14\x00\x00\x00\x12crc64\x00\x00\x00\x00\x00\x00\x00 \x00\x00'
>>> bson_str = bson.decode()
>>> bson_str
{u'crc64': 9007199254740992}
>>> 

并运行此脚本:

db.foo.save({"_id" : 1, "crc64" : long(9007199254740992)});

for doc in db.foo.find({"_id" : 1 }):
    crc = doc["crc64"]
    print("crc type: " + str(type(crc)))

打印:

crc type: <type 'int'>

从 mongo shell:

> db.foo.findOne()
{ "_id" : 1, "crc64" : NumberLong("9007199254740992") }
> 

【讨论】:

  • 您的 long 还不够长。尝试使用 2**64 而不是 9007199254740992 执行上述操作。它会引发溢出错误,因为就 mongo 而言,这个数字太大了。除非您将其转换为 int64(已签名)。
  • 正如我所说,64位数字是有符号的,这意味着[-2^63, 2^63-1]范围,所以你不能有2^64。 9007199254740992 肯定不是 32 位整数。
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 2011-11-10
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 2016-06-28
相关资源
最近更新 更多