我正在尝试使用mongoose对来自nodejs的聚合中的Date对象进行操作。我的DB文档具有以下形式:
{"__v" : 0,
"dob" : ISODate("1991-04-10T11:41:02.361Z"),
"gender" : "MALE",
...}
我正在尝试如下计算当前年龄,这在robomongo和shell中工作正常
db.p.aggregate([
{$project: { "age": {$divide: [{ $subtract: [ new ISODate(), "$dob" ] },31558464000]}}}
])
输出:
"result" : [
{
"age" : 23.00286577030492,
"gender" : "MALE"
},
...
]
但我无法从猫鼬内部开始工作。如果我使用相同的查询,则ISODate未定义如下:ISODate is not defined
所以我建议尝试不同的Date()
变体{$project: { "age": {$divide: [{ $subtract: [ new Date(), "$dob" ] }, 31558464000] }}}
RESULT: [MongoError: exception: cant $subtract a String from a Date]
{$project: {
"age": {$divide: [{ $subtract: [ new Date(), new Date("$dob") ] }, 31558464000] },
"dob2": { $subtract: [ new Date("$dob"), 1 ] }, "dob": 1}}
RESULT: [ { _id: '10000000000000000000000b',
dob: '1991-04-10T11:41:02.361Z',
age: 44.27401739168928, <-- wrong age
dob2: Thu Jan 01 1970 00:59:59 GMT+0100 (CET) }, <-- wrong date
... ]
{$project: {
"age": {$divide: [{ $subtract: [ new Date(), Date("$dob") ] }, 31558464000] },
"dob": 1}}
RESULT: [MongoError: exception: cant $subtract a String from a Date]
如果我尝试将String转换为聚合中的日期,则无法正确转换但在聚合之外它可以正常工作:
var dateISOString = "1991-04-10T11:41:02.361Z";
var dateTimeDate = new Date(startTimeISOString);
RESULT: Wed Apr 10 1991 13:41:02 GMT+0200 (CEST) 23.00290412198135 <-- correct Date
所以我不能使用直接引用$ dob,因为它被视为String。我不能使用ISODate转换,因为它没有定义,我不能使用新的Date(),因为转换在聚合框架中是错误的。我已广泛搜索,但无法找到问题的解决方案。如何将我的ISODate字符串转换为正确的日期或直接在第一个地方获取日期,而不是聚合。非常感谢帮助。
MongoDB: "version" : "2.4.9",
"sysInfo" : "Linux SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49",
nodejs: v0.10.21
在Neil的回复后编辑:
function test( user, callback ) {
var mongoose = require( 'mongoose' );
mongoose.connect( 'mongodb://localhost:8080/11', function( ) { } );
var
collection;
if( err ) {
callback( err );
} else {
collection = mongoose.connections[0].collection( 'aggregate' );
collection.aggregate([
{ "$project": {
"_id": 0,
"this": { "$divide": [
{ "$subtract": [ new Date(), "$dob" ]},
31558464000
]}
}}
], function( err, res ) {
console.warn( 'collection.doneCb.1', res, JSON.stringify( res ) );
callback( err, res );
} );
/*collection.aggregate( query, function( err, res ) {
console.warn( 'collection.doneCb.1', res, JSON.stringify( res ) );
callback( err, res );
} );*/
} );
} );
}
};
这会产生:
{ [MongoError: exception: cant $subtract a String from a Date]
name: 'MongoError',
errmsg: 'exception: cant $subtract a String from a Date',
code: 16613,
ok: 0 }
谢谢!
答案 0 :(得分:1)
所以只是为了澄清输出。 ISODate
是MongoDB shell的内部函数,或者在驱动程序函数中提供。但是对于JavaScript,只需使用Date()
对象构造函数:
鉴于数据:
{ "date" : ISODate("1971-09-22T00:00:00Z") }
以下查询:
db.birthdays.aggregate([
{ "$project": {
"_id": 0,
"this": { "$divide": [
{ "$subtract": [ new Date(), "$date" ]},
31558464000
]}
}}
])
产地:
{ "this" : 42.552055734461604 }
即使我很抱歉这样说; - )