我需要在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", "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}}
请注意,二进制数据类型表示为整数,而不是十六进制字符串。
现在进行比较,使用MongoDB C ++驱动程序检索相同的两条记录并使用jsonString()
方法打印它们。这是输出:
{ "_id" : { "$oid" : "51acf66886174308b610d950" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "00" } }
{ "_id" : { "$oid" : "51acf66c86174308b610d951" }, "name" : "Alex", "data" : { "$binary" : "12345678", "$type" : "80" } }
现在类型是十六进制字符串,而不是数字。
因此,相同的记录具有不同的JSON表示形式,具体取决于它是使用C ++驱动程序还是Java驱动程序检索的。当某些软件使用Java驱动程序而某些软件使用C ++驱动程序时,这种差异会在混合环境中产生问题。有什么建议如何解决问题(除了通过更改驱动程序代码)?哪一个是正确的 - 将类型表示为十六进制字符串的C ++驱动程序或Java驱动程序?我的理解是C ++驱动程序返回的表示是正确的,但有人可以证实这一点吗?
MongoDB http接口也返回十六进制字符串表示 - 可能是因为支持REST接口(mongod)的后端是用C ++编写的。
我正在使用Java驱动程序版本2.11.1和C ++驱动程序版本2.4.3。
答案 0 :(得分:0)
这里没有区别。 数据是相同的,只有使其可读的格式化程序以不同的格式呈现它。
[...]使用
jsonString()
方法打印它们
这就是重点,你看着格式化的输出:“0x80”,“80”,128和-128 可以都意味着同样的事情。始终根据某些惯例解释数据。在“0x80”的情况下,“0x” - 前缀是用于指示十六进制表示法的有点普遍的约定。 “80”要求您知道数据应解释为十六进制字符串并且对应于二进制值1000000,对于整数等于十进制值128.如果该值被解释为byte
但是,它对应于-128。
您的代码不应查看格式化的输出,而应与具有明确定义类型的字段或属性(如int
)进行比较。然后,你可以写
if(a.Type == 128) { ... }
无论编程语言的 formatter 输出什么,哪个值都应该为正确的值。 (如果a.Type
为byte
,则必须与-128进行比较。如果与128进行比较,大多数编程语言都会发出警告或错误,因为128大于最大可表示的签名8位值,又称字节)。
顺便说一句,当您查看对象id的表示时,不同的格式更加引人注目:在mongo控制台中,它显示为ObjectId("51acf66886174308b610d950")
,C ++ json格式化程序显示"_id" : {"$oid" : "51acf66886174308b610d950"}
。同样,它是相同的数据,但这里的字符串看起来相同,而它周围的脚手架看起来不同。
答案 1 :(得分:0)
这是Java驱动程序中的bug。