MongoDB-使用C++;和Java驱动程序
我需要在MongoDB集合中保留一些二进制数据。当我使用C++驱动程序或java驱动程序检索同一条记录时,我的文档的JSON表示方式似乎不同。 这里有一个例子。使用Mongo shell在MongoDB集合中插入三条记录:MongoDB-使用C++;和Java驱动程序,mongodb,mongodb-java,Mongodb,Mongodb Java,我需要在MongoDB集合中保留一些二进制数据。当我使用C++驱动程序或java驱动程序检索同一条记录时,我的文档的JSON表示方式似乎不同。 这里有一个例子。使用Mongo shell在MongoDB集合中插入三条记录: db.binary_test.insert({"name":"Alex", "data" :BinData("0x00", "12345678")}) db.binary_test.insert({"name":"Alex", "data" :BinData("0x80",
db.binary_test.insert({"name":"Alex", "data" :BinData("0x00", "12345678")})
db.binary_test.insert({"name":"Alex", "data" :BinData("0x80", "12345678")})
第一条记录使用二进制类型0x00(通用);第二个参数为-0x80(用户定义)
使用Mongo Shell检索这些记录:
db.binary_test.find().pretty()
输出:
{
"_id" : ObjectId("51acf66886174308b610d950"),
"name" : "Alex",
"data" : BinData(0,"12345678")
}
{
"_id" : ObjectId("51acf66c86174308b610d951"),
"name" : "Alex",
"data" : BinData(128,"12345678")
}
请注意,标记表示为数字,而不是十六进制字符串
现在,使用非常简单的Java程序检索相同的记录,并使用严格的序列化程序将其转换为JSON:
ObjectSerializer serializer = JSONSerializers.getStrict();
System.out.println(serializer.serialize(doc));
以下是输出:
{ "_id" : { "$oid" : "51acf66886174308b610d950"} , "name" : "Alex" , "data" : { "$binary" : "12345678" , "$type" : 0}}
{ "_id" : { "$oid" : "51acf66c86174308b610d951"} , "name" : "Alex" , "data" : { "$binary" : "12345678" , "$type" : -128}}
{ "_id" : { "$oid" : "51acf66886174308b610d950" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "00" } }
{ "_id" : { "$oid" : "51acf66c86174308b610d951" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "80" } }
请注意,二进制数据类型表示为整数,而不是十六进制字符串
现在比较使用MunGDB C++驱动程序检索相同的两个记录,并使用<代码> JSONSTRIN()/<代码>方法打印它们。以下是输出:
{ "_id" : { "$oid" : "51acf66886174308b610d950"} , "name" : "Alex" , "data" : { "$binary" : "12345678" , "$type" : 0}}
{ "_id" : { "$oid" : "51acf66c86174308b610d951"} , "name" : "Alex" , "data" : { "$binary" : "12345678" , "$type" : -128}}
{ "_id" : { "$oid" : "51acf66886174308b610d950" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "00" } }
{ "_id" : { "$oid" : "51acf66c86174308b610d951" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "80" } }
现在类型是十六进制字符串,而不是数字
<> P>因此,同一个记录有不同的JSON表示,取决于它是使用C++驱动程序还是java驱动程序检索的。这种差异在混合环境中产生问题,当一些软件使用java驱动程序时,有些使用C++驱动程序。有没有解决问题的建议(除了更改驱动程序代码)?哪一个是正确的——C++驱动程序,它表示类型是十六进制字符串,还是java驱动程序?我的理解是C++驱动程序返回的表达式是正确的,但是有人能确认吗?
MangGDB HTTP接口还返回十六进制字符串表示-可能是因为支持REST接口的后端(MunGod)是用C++编写的。
我使用的是java驱动程序2.1.1和C++驱动程序2.4.3.这里没有区别。数据是相同的,只有使其可读的格式化程序以不同的格式呈现 […]使用
jsonString()
方法打印它们
这就是重点,您查看格式化输出:“0x80”、“80”、“128”和-128可能都意味着相同的事情。数据总是按照某种约定进行解释。在“0x80”的情况下,“0x”-前缀是表示十六进制表示法的一种较为普遍的约定。“80”要求您知道数据应解释为十六进制字符串,并对应于1000000的二进制值,对于整数,该值等于128的十进制值。但是,如果该值被解释为字节
,则它对应于-128
代码不应查看格式化的输出,而应与具有定义良好类型(如int
)的字段或属性进行比较。然后,你就可以写了
if(a.Type == 128) { ... }
对于正确的值,无论编程语言的格式化程序输出什么,它都应计算为true。(如果a.Type
是byte
,则必须与-128进行比较。如果与128进行比较,大多数编程语言都会发出警告或错误,因为128大于最大的可表示有符号8位值,即字节)
顺便说一下,当你查看对象ID的表示时,不同的形式更为显著:在Mango控制台中,它被呈现为<代码> ObjectId(“5ACF66 86174308B610D950”),C++ JSON格式器显示
字节[]
的全水化POCO/POJO,会发生什么情况?该错误报告是由OP发布的。