【问题标题】:Return actual type of a field in MongoDB返回 MongoDB 中字段的实际类型
【发布时间】:2011-03-13 14:52:32
【问题描述】:

在 MongoDB 中,使用 $type,可以根据字段是否匹配 BSON 数据类型来过滤搜索(请参阅 DOCS)。

例如。

db.posts.find({date2: {$type: 9}}, {date2: 1})

返回:

{ 
    "_id" : ObjectId("4c0ec11e8fd2e65c0b010000"), 
    "date2" : "Fri Jul 09 2010 08:25:26 GMT" 
}

我需要一个查询来告诉我该字段的实际类型,对于集合中的每个字段。 MongoDB 可以做到这一点吗?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    好的,这里有一些相关的问题可能会有所帮助:

    Get all field names 在使用 map-reduce 的集合中。

    这里是a recursive version,它列出了所有可能的字段。

    希望这可以帮助您入门。但是,我怀疑您将在此请求中遇到一些问题。这里有两个问题:

    1. 我找不到 JSON 的“gettype”函数。您可以通过 $type 进行查询,但看起来您实际上不能在字段上运行 gettype 函数并将其映射回 BSON 类型。
    2. 一个字段可以包含多种类型的数据,因此您需要一个计划来处理这个问题。即使在你不知道的情况下,Mongo 也可以将一些数字存储为整数,而其他浮点数并不明显。其实用 PHP 驱动是完全可以做到的。

    因此,如果您假设您可以解决问题 #1,那么您应该能够使用 “获取所有字段名称” 的细微变化来解决问题 #2。

    它可能看起来像这样:

    "map" : function() { for (var key in this) { emit(key, [ typeof value[key] ]); } }
    "reduce" : function(key, stuff) { return (key, add_to_set(stuff) ); }
    

    所以基本上你会在 map 函数中发出 keytype of key value (作为一个数组)。然后从 reduce 函数中为每种类型添加唯一的条目。

    在运行结束时你会得到这样的数据

    {"_id":[255], "name" : [1,5,8], ... }

    当然,这需要大量工作,根据您的实际问题,您可能只想确保(通过您的代码)始终输入正确类型的数据。数据到DB之后再找数据的类型肯定是一件很痛苦的事。

    【讨论】:

      【解决方案2】:

      在 mongo shell 中输入以下查询

        typeof db.employee.findOne().first_name
      

      语法

       typeof db.collection_name.findOne().field_name
      

      【讨论】:

      • 这将给出 JS 类型,可能与 BSON 类型不同。例如,如果你执行 typeof db.employee.findOne()._id,你会得到“string”,但 BSON 类型是“Object id”。
      【解决方案3】:

      注意到a=5;a.constructor.toString() 打印function Number() { [native code] },可以执行类似的操作:

      db.collection.mapReduce(
      function() {
          emit(this._id.constructor.toString()
             .replace(/^function (\S+).+$/,  "$1"), 1);
      }, 
      function(k, v) {
          return Array.sum(v);
      }, 
      { 
          out: { inline: 1 } 
      });
      

      【讨论】:

        【解决方案4】:

        从 MongoDB 3.4 开始,您可以使用 $type 聚合运算符返回字段的类型。

        db.posts.aggregate( 
            [ 
                { "$project": { "fieldType": {  "$type": "$date2"  } } } 
            ]
        )
        

        产生:

        { 
            "_id" : ObjectId("4c0ec11e8fd2e65c0b010000"), 
            "fieldType" : "string" 
        }
        

        【讨论】:

        • mongodb 文档中的这个例子更清晰一些(基本上把上面的“$date2”变成了“$fieldType”),比如这里:db.coll.aggregate([{ $project: { a : { $type: "$a" } } }])
        【解决方案5】:

        利用 styvane 查询,我添加了一个 $group 列表,以便在我们有不同的数据类型时更容易阅读。

        db.posts.aggregate( 
        [ 
            { "$project": { _id:0, "fieldType": {  "$type": "$date2"  } } },
            {"$group": { _id: {"fieldType": "$fieldType"},count: {$sum: 1}}}
        ])
        

        并得到这样的结果:

        { "_id" : { "fieldType" : "missing" }, "count" : 50 }
        { "_id" : { "fieldType" : "date" }, "count" : 70 }
        { "_id" : { "fieldType" : "string" }, "count" : 10 }
        

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        猜你喜欢
        • 2021-03-11
        • 2017-06-07
        • 2019-08-04
        • 2018-11-19
        • 2011-08-11
        • 1970-01-01
        • 2015-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多