我正在研究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"
结果吗?
答案 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时,实际上会丢失此对象。
您可以通过以下两种方式解决:
$date
属性(我相信),您可以检查isset
是否该字段是日期类型