如何在 MongoDB 文档中存储 unsigned long long (uint64_t) 值?

Posted

技术标签:

【中文标题】如何在 MongoDB 文档中存储 unsigned long long (uint64_t) 值?【英文标题】:How to store unsigned long long (uint64_t) values in a MongoDB document? 【发布时间】:2012-12-21 17:21:49 【问题描述】:

我想在 MongoDB 文档中存储 unsigned long long (uint64_t) 类型的数字,我该怎么做?

我需要使用 unsigned long long,因为我正在使用 Twitter API,它使用无符号 64 位整数 https://dev.twitter.com/docs/twitter-ids-json-and-snowflake

无符号64位整数类型的范围需要用8个字节表示,数据范围为0到18,446,744,073,709,551,615。

我正在使用C++ MongoDB driver,BSONArrayBuilder 类的 append 成员函数没有 unsigned long long 的重载,只有 long long。

当我尝试使用 uint64_t 类型的 id 调用 arrayBuilder.append(id) 时,出现错误 G++ 4.7.2:

MongoDB/mongo/db/../bson/bson-inl.h:342:9: error: call of overloaded ‘append(const char*&, long long unsigned int&)’ is ambiguous
MongoDB/mongo/db/../bson/bsonobjbuilder.h:167:25: note: mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, bool)
MongoDB/mongo/db/../bson/bsonobjbuilder.h:175:25: note: virtual mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, int)
MongoDB/mongo/db/../bson/bsonobjbuilder.h:183:25: note: mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, unsigned int)
MongoDB/mongo/db/../bson/bsonobjbuilder.h:188:25: note: virtual mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, long long int)
MongoDB/mongo/db/../bson/bsonobjbuilder.h:244:25: note: virtual mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, double)
MongoDB/mongo/db/../bson/bsonobjbuilder.h:324:25: note: mongo::BSONObjBuilder& mongo::BSONObjBuilder::append(const mongo::StringData&, mongo::Date_t)
我知道BSON specification 将 int64 定义为 8 个字节(64 位 有符号整数)。 我不想为 ID 使用字符串。

【问题讨论】:

【参考方案1】:

由于 MongoDB/BSON 仅支持带符号的 64 位整数,因此在与数据库交互时,您需要将 64 位无符号值转换为 long long

仍然使用所有 64 位,因此您不会丢失任何可用的无符号范围,对于那些使用最高有效位的值,它只会在数据库中显示为负值。

【讨论】:

@BadDesign 这些值在转换时(以及在数据库中)将变为负数,但只要您在读出时将它们转换回 uint64_t 就可以了。 这确实是最好的解决方案,只要您不希望 Mongo 对这些值进行任何计算。 非常感谢@JohnnyHK!【参考方案2】:

恕我直言,恕我直言,您能做的最好的事情就是重新考虑您不使用字符串作为 ID 的决定,因为:

    由于存储 64B 双精度(通常是 3 个附加字段和字段名称)时 bson 内部的开销量,它可能比以往任何时候都高效得多(请参阅 'floatApprox'、'top'、bottom' here、here 和 here)

    您使用的 twitter API 已将它作为 id_str 提供,这是有充分理由的

    如果在 JS 中转换这些数字,您将遇到真正的麻烦 你曾经碰巧使用过 mongodb map reduce

【讨论】:

以上是关于如何在 MongoDB 文档中存储 unsigned long long (uint64_t) 值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在mongodb的同一个集合中存储多个文档

如何使用 MongoDB 存储和搜索大型文档?

mongodb怎么插入多个文档

如何使用Spring框架加密文档中的所有MongoDB字段

MongoDB 插入文档

使用 MongoDB .Net 驱动程序对存储在文档字段中的数组进行分页