如果字段是日期类型,我怎么能在mongodb中知道?

时间:2012-09-27 11:27:49

标签: node.js mongodb date

我正在研究NodeJS + Mongodb应用。

我刚刚使用控制台客户端将一条记录插入到mongodb中:

db.user.save({myId:11111, myDate: ISODate("2012-04-30T00:00:00.000Z")})

问题是,当我在node.js时,我需要知道“myDate”字段是否真的是Date类型,以便执行数据范围查询等。

我尝试了以下内容。

1。在mongo客户端控制台上:

typeof db.user.myDate --> It returns "Object"
db.user.myDate instanceof Date --> It returns "false"

2。在我的Nodejs代码上,

我正在尝试调用此getTypeMembers函数的类型。 (obj来自db查询)

exports.getTypeMembers = function(obj) {
obj = JSON.parse(JSON.stringify(obj)

for(var _k in obj){
    if(Object.prototype.toString.call(obj[_k]) === '[object Array]' ) {
        obj[_k] = "Array";
    }
    else if(typeof(obj[_k])=="object"){
        obj[_k] = this.getTypeMembers(obj[_k]);
    }else{
        obj[_k] = typeof (obj[_k]);
    }
}
return obj;

};

当我需要"String"

时,我在此方法中获得的是:"Date"

还有其他方法可以获得某种"Date"结果吗?

4 个答案:

答案 0 :(得分:5)

我终于找到了解决方案。

正如@christkv所说,一旦你调用JSON stringify,所有原始类型肯定会丢失。 所以,以这种方式思考,我的方法getTypeMembers对我来说非常有效。

请注意,obj参数来自DB,并且“_id”(mongodb标识符)是直接省略的,以避免在执行递归函数时出现问题:

exports.getTypeMembers = function(obj) {
    for(var _k in obj){
        if (_k =="_id") continue;
        if (Object.prototype.toString.call(obj[_k]) === "[object Number]"){
            obj[_k] = "Number";
        }else if (Object.prototype.toString.call(obj[_k]) === "[object String]"){
            obj[_k] = "String";
        }else if (Object.prototype.toString.call(obj[_k]) === "[object Date]"){
            obj[_k] = "Date";
        } else if(Object.prototype.toString.call(obj[_k]) === '[object Array]' ) {
            obj[_k] = "Array";
        } else if(typeof(obj[_k])=="object"){
            obj[_k] = this.getTypeMembers(obj[_k]);
        } else{
            obj[_k]  = (typeof obj[_k])[0].toUpperCase() + (typeof obj[_k]).slice(1);
        }
    }
    return obj;
};

在Mongo控制台部分,我只能得到执行以下操作的类型:

db.user.find({},{myDate:1}).forEach(function(f) { print (f.myDate instanceof Date) } );

但如果我这样做,

typeof db.user.myDate --> It returns "Object"
db.user.myDate instanceof Date --> It returns "false"

我仍然没有理解为什么。

答案 1 :(得分:2)

我对使用

感到有些困惑
db.user.myDate
在你的例子中

。你是否在node-mongodb-native给你的Db对象上进行了这个确切的调用?如果是这样,你应该得到未定义,因为你实际上并没有查询数据库,而是检查Db javascript对象的属性(几乎所有确定的属性都没有)。

您可以从node.js进程发布您正在运行的代码吗?我测试了你的代码,使用相同的shell插入,一旦我从node.js中的数据库中检索了文档,

doc.myDate instanceof Date

返回true。

我也不熟悉你的应用程序,但在我不知道数据类型的情况下查询集合似乎是不明智的。为什么您不确定其他应用程序用于myDate字段的值是什么类型?

修改:

var coll = new mongo.Collection(client, 'user');
    coll.find({}).toArray(function(err, docs) {
    docs.forEach(function (doc) {
        console.log(doc);
        console.log(doc.myDate instanceof Date);
    });
});

在我向相同的shell插入后在nodejs中运行时,为我记录“true”。如果你运行它会发生什么?

答案 2 :(得分:1)

您可以使用$ type运算符查询特定类型的字段:

db.col.query({a: {$type: 9}})

9是日期类型的数字,请参阅http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24type

至于确定node.js中的类型,它取决于你的驱动程序。我没有使用过,但它可能是一个特定的原型,就像ObjectId一样。也许您可以检查对象并查找构造函数名称。

答案 3 :(得分:1)

根据您的最新编辑判断我相信我看到了问题。您正在将文档解析为JSON。与BSON不同,JSON不支持BSON对象的文字创建和存储。 ISODate对象是BSON数据类型。

因此,当您转换为JSON时,实际上会丢失此对象。

您可以通过以下两种方式解决:

  • 在检查字段类型
  • 之前,请勿转换为JSON
  • 每个对象都有属性。日期没有什么不同,它应该有一个$date属性(我相信),您可以检查isset是否该字段是日期类型