【问题标题】:MongoDB Java driver: Undefined values are not shownMongoDB Java 驱动程序:未显示未定义的值
【发布时间】:2013-06-20 12:44:04
【问题描述】:

打开 mongo shell 并创建一个未定义值的文档:

> 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”对已经消失了! (键和值)。

为什么?是bug吗?

谢谢

【问题讨论】:

    标签: java json mongodb bson


    【解决方案1】:

    目前,java 驱动程序不支持 undefined,因为 java 中没有等效的映射。

    其他驱动程序(例如 pymongo 和 js shell)通过在表示数据时将 undefined 转换为 None 以不同方式处理此问题,但它是一个单独的数据类型,在 bson spec 中已弃用。

    如果您在 java 驱动程序中需要它,那么您必须编写自己的解码器工厂,然后像这样设置它:

    collection.setDBDecoderFactory(MyDecoder.FACTORY);
    

    定义了undefined 和工厂处理的最小示例可在 github 上的 horn of mongo 存储库中找到。

    【讨论】:

      【解决方案2】:

      我明白了,创建工厂可能是一个解决方案。

      无论如何,可能许多开发人员会发现在驱动程序中启用映射以自动将“未定义”值转换为“空”值的可能性很有用。例如,通过调用 mapUndefToNull() 方法:

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

      在我的情况下,我在我的集​​合上运行 MapReduce(它是 Javascript 代码),并且我必须将未定义的值(在访问不存在的键时生成)显式转换为 null,以避免 Java驱动程序将其删除:

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

      因此,作为建议,我希望将 mapUndefToNull() 方法添加到 Java 驱动程序中。如果可能的话。

      谢谢

      【讨论】:

        猜你喜欢
        • 2021-05-24
        • 2013-07-06
        • 2017-12-10
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        • 2021-01-06
        • 1970-01-01
        相关资源
        最近更新 更多