2013-06-20 92 views
0

打開蒙戈外殼和一個未定義的值創建文檔:MongoDB的Java驅動程序:未定義的值未顯示

> mongo 
MongoDB shell version: 2.4.0 
connecting to: test 
> use mydb 
switched to db mydb 
> db.mycol.insert({a_number:1, a_string:"hi world", a_null:null, an_undefined:undefined}); 
> db.mycol.findOne(); 
{ 
     "_id" : ObjectId("51c2f28a7aa5079cf24e3999"), 
     "a_number" : 1, 
     "a_string" : "hi world", 
     "a_null" : null, 
     "an_undefined" : null 
} 

我們可以看到,JavaScript的翻譯「未定義」值(存儲在數據庫中)到一個「空」值,當顯示給用戶時。但是,在db中,值仍然是「未定義的」,正如我們將要用java看到的那樣。

讓我們創建一個 「bug_undefined_java_mongo.java」 文件,包含以下內容:

import com.mongodb.DB; 
import com.mongodb.DBCollection; 
import com.mongodb.DBCursor; 
import com.mongodb.MongoClient; 


public class bug_undefined_java_mongo 
{ 

    String serv_n = "myserver";  // server name 
    String db_n = "mydb";   // database name 
    String col_n = "mycol";  // collection name 


    public static void main(String[] args) 
    {   
     new bug_undefined_java_mongo().start();   
    } 


    public void start() 
    { 

     pr("Connecting to server ...");  
     MongoClient cli = null; 
     try 
     { 
      cli = new MongoClient(serv_n);   
     } 
     catch (Exception e) 
     { 
      pr("Can't connecto to server: " + e); 
      System.exit(1); 
     } 
     if (cli == null) 
     { 
      pr("Can't connect to server"); 
      System.exit(1); 
     } 


     pr("Selecting db ..."); 
     DB db_res = cli.getDB(db_n); 


     pr("Selecting collection ...");  
     DBCollection col = db_res.getCollection(col_n); 


     pr("Searching documents ..."); 
     DBCursor cursor = null; 
     try 
     { 
      cursor = col.find(); 
     } 
     catch (Exception e) 
     { 
      pr("Can't search for documents: " + e); 
      System.exit(1); 
     } 


     pr("Printing documents ..."); 
     try 
     { 
      while (cursor.hasNext()) 
      { 
       Object doc_obj = cursor.next();     
       System.out.println("doc: " + doc_obj); 
      } 
     } 
     catch (Exception e) 
     { 
      pr("Can't browse documents: " + e); 
      return; 
     } 
     finally 
     { 
      pr("Closing cursor ..."); 
      cursor.close(); 
     } 

    } 


    public void pr(String cad) 
    { 
     System.out.println(cad); 
    }  

} 

編譯並運行它之後,我們得到這樣的:

Connecting to server ... 
Selecting db ... 
Selecting collection ... 
Searching documents ... 
Printing documents ... 
doc: { "_id" : { "$oid" : "51c2f0f85353d3425fcb5a14"} , "a_number" : 1.0 , "a_string" : "hi world" , "a_null" : null } 
Closing cursor ... 

我們看到,「a_null: null「對,但是......」an_undefined:undefined「對已經消失了! (鍵和值)。

爲什麼?這是一個錯誤嗎?

謝謝

回答

2

目前undefined不是由Java驅動程序,因爲沒有在java中相當於映射支持。

其他驅動程序如pymongo和JS殼由表示數據時鑄造undefinedNone不同的方式處理這一點,但是它是一個單獨的數據類型和在bson spec已棄用。

如果你需要在Java驅動程序,那麼你將不得不編寫自己的解碼器工廠,然後將其設置像這樣:

collection.setDBDecoderFactory(MyDecoder.FACTORY); 

已經定義了處理爲undefined和工廠小例子可以用github在horn of mongo回購。

0

我看到,創建工廠可能是一個解決方案。

無論如何,可能很多開發人員會發現它有助於在驅動程序中啓用映射的自動將「未定義」值轉換爲「空值」的可能性。例如,通過調用mapUndefToNull()方法:

cli = new MongoClient(myserver); 
cli.mapUndefToNull(true); 

就我而言,我對我的藏品運行MapReduce的(這是Javascript代碼),和我有明確轉換未定義的值(產生訪問到不存在的密鑰時)爲空,以避免Java驅動程序將其刪除:

try { value = this[ key ] } catch(e) {value = null} 
if (typeof value == "undefined") value = null;  // avoid Java driver to remove it 

所以,作爲一個建議,我想加入到Java驅動程序的mapUndefToNull()方法。如果可能的話。

謝謝

相關問題