【发布时间】:2016-09-20 20:28:05
【问题描述】:
有没有办法按原样从 MongoDB 获取文档,而不是将某些字段转换为包含 $ 字段的对象?
例如,我有一个名为 timestamp 的字段,我在其中存储了一个 long 值。它过去只返回一个值,然后突然在大约一周后开始返回一个对象:
{
"$numberLong": "1474402633708"
}
这与嵌套对象的 _id 字段相同。它正在返回“_id”,并在某些时候切换为返回一个带有 $oid 的对象,例如顶层。我真的需要它至少保持一致。
这是来自 MongoDB 客户端的屏幕截图。第一个序列化为 JSON 时不返回 $numberLong 而最后一个返回。
这只是某处的配置吗?这完全没有意义。
这里是从控制台消除任何关于时间戳字段的数据不同的疑问。
> db["page"].find()
{ "_id" : ObjectId("57dd99ab390a777a9720e8c2"), "entries" : [ { "widget" : { "_id" : ObjectId("57dec085390a777a9720e8c5"), "_db" : "system-s", "_col" : "card" }, "width" : -1, "height" : -1 }, { "widget" : { "_id" : ObjectId("57df6119390a778641f4fd25"), "_db" : "system-s", "_col" : "card" }, "width" : -1, "height" : -1 } ], "title" : "Simple 2", "timestamp" : 1474257177398 }
{ "_id" : ObjectId("57e171ff303c2807d6ea1dd6"), "entries" : [ { "widget" : { "_id" : ObjectId("57e1720b303c2807d6ea1dd9"), "_db" : "system-s", "_col" : "card" }, "width" : -1, "height" : -1 } ], "title" : "Test 2", "timestamp" : 1474392587984 }
我目前正在使用 MongoDB Java lib v3.3.0 对其进行测试。这是代码以防万一。
//the endpoint is exposed using Spark
get("/db/:collection/get/:id", (request, response) -> {
String collectionName = request.params(":collection");
String id = request.params(":id");
Document doc = getDocument(collectionName, id);
return doc.toJson(); //this is where I see the issues
});
public Document getDocument(String collectionName, String id){
MongoCollection<Document> coll = db.getCollection(collectionName);
BasicDBObject query = new BasicDBObject();
query.put("_id", new ObjectId(id));
FindIterable<Document> itr = coll.find(query);
Document doc = itr.first();
if(doc != null){
return doc;
}
return null;
}
这是 Javascript 中的一种解决方法,可确保数据一致,以防您也遇到此问题。这段代码使用了一些 jQuery 函数,但是如果你不使用 jQuery,你可以替换它们。
function scrub(obj){
if(obj.$oid){
return obj.$oid;
}else if(obj.$numberLong){
return parseInt(obj.$numberLong);
}else if(obj.$numberInt){
return parseInt(obj.$numberInt);
}else if(obj.$date){
if($.isPlainObject(obj.$date) && obj.$date.$numberLong){
return parseInt(obj.$date.$numberLong);
}else{
return parseInt(obj.$date);
}
}else{
$.each(obj, function(k, v){
if($.isPlainObject(v)){
obj[k] = scrub(v);
}else if($.isArray(v)){
$.each(v, function(kk, vv){
if($.isPlainObject(vv)){
v[kk] = scrub(vv);
}
});
}
});
}
return obj;
};
更新 1:
在逐行调试之后,我发现对于 long 值以某种方式被解释为 double (指数值)的情况,然后我得到了预期值,而那个值被解释为 long (int64),我因为默认模式是 STRICT,所以要返回 $numberLong。现在的问题是如何将 long 值存储为 double 和 long 。
【问题讨论】:
-
是在您的应用程序中使用驱动程序还是在 Mongo shell 中发生?
-
使用 MongoDB Java 客户端时会发生这种情况。
-
更具体地说,我在 toJson 方法调用的返回值中看到了这一点。
标签: java mongodb object numbers