milisegundos getseconds getmilliseconds from fecha convertir javascript mongodb type-conversion aggregation-framework

javascript - getseconds - Convertir la fecha de milisegundos a objeto ISODate



js get microtime (4)

Intento agregar registros en una collección de MongoDB por hora y necesito convertir la fecha almacenada como marca de tiempo (milisegundos) a ISODate para que pueda usar los operadores de fecha incorporados de framework agregado ($ hora, $ mes, etc.)

Los registros se almacenan como

{ "data" : { "UserId" : "abc", "ProjId" : "xyz"}, "time" : NumberLong("1395140780706"), "_id" : ObjectId("532828ac338ed9c33aa8eca7") }

Estoy intentando usar una consulta agregada del siguiente tipo:

db.events.aggregate( { $match : { "time" : { $gte : 1395186209804, $lte : 1395192902825 } } }, { $project : { _id : "$_id", dt : {$concat : (Date("$time")).toString()} // need to project as ISODate } }, // process records further in $project or $group clause )

que produce resultados de la forma:

{ "result" : [ { "_id" : ObjectId("5328da21fd207d9c3567d3ec"), "dt" : "Fri Mar 21 2014 17:35:46 GMT-0400 (EDT)" }, { "_id" : ObjectId("5328da21fd207d9c3567d3ed"), "dt" : "Fri Mar 21 2014 17:35:46 GMT-0400 (EDT)" }, ... }

Deseo extraer la hora, el día, el mes y el año a partir de la fecha, pero dado que el tiempo se proyecta como una cadena, no puedo utilizar los operadores de fecha incorporados del marco agregado ($ hora, etc.).

¿Cómo puedo convertir el tiempo de milisegundos a la fecha ISO para hacer algo como lo siguiente?

db.events.aggregate( { $match : { "time" : { $gte : 1395186209804, $lte : 1395192902825 } } }, { $project : { _id : "$_id", dt : <ISO date from "$time"> } }, { $project : { _id : "$_id", date : { hour : {$hour : "$dt"} } } } )


use esto si la función {$add: [new Date(0), "$time"] } devuelve un string type no sea un ISO date type

Utilizo toda esa opción pero sigo fallando, porque mi nueva fecha de $project devuelve un string type como ''2000-11-2:xxxxxxx'' no date type como ISO(''2000-11-2:xxxxxxx'') para cualquiera que tiene el mismo problema conmigo use esto.

db.events.aggregate( { $project : { _id : "$_id", dt : {$add: [new Date(0), "$time"]} } }, { $project : { _id : "$_id", "year": { $substr: [ "$dt", 0, 4 ] }, "month": { $substr: [ "$dt", 5, 2] }, "day": { $substr: [ "$dt", 8, 2 ] } } } );

el resultado será

{ _id: ''59f940eaea87453b30f42cf5'', year: ''2017'', month: ''07'', day: ''04'' },

puede obtener horas o minutos si lo desea dependiendo de qué string desea subset , luego puede group eso de nuevo según la misma fecha, mes o año


En realidad, es posible, el truco es agregar el tiempo de su milisegundo a un objeto Date () de cero milisegundos usando una sintaxis similar a:

dt : {$add: [new Date(0), "$time"]}

Modifiqué tu agregación desde arriba para producir el resultado:

db.events.aggregate( { $project : { _id : "$_id", dt : {$add: [new Date(0), "$time"]} } }, { $project : { _id : "$_id", date : { hour : {$hour : "$dt"} } } } );

El resultado es (con una entrada de sus datos de muestra):

{ "result": [ { "_id": ObjectId("532828ac338ed9c33aa8eca7"), "date": { "hour": 11 } } ], "ok": 1 }


Para devolver una fecha válida de BSON, todo lo que necesita es una pequeña fecha de "matemáticas" usando el operador $add . Necesita agregar una new Date(0) a la marca de tiempo. La new Date(0) representa el número de milisegundos desde la época de Unix (1 de enero de 1970) y es una abreviación de new Date("1970-01-01") .

db.events.aggregate([ { "$match": { "time": { "$gte" : 1395136209804, "$lte" : 1395192902825 } } }, { "$project": { "hour": { "$hour": { "$add": [ new Date(0), "$time" ] } }, "day": { "$dayOfMonth": { "$add": [ new Date(0), "$time" ] } }, "month": { "$month": { "$add": [ new Date(0), "$time" ] } }, "year": { "$year": { "$add": [ new Date(0), "$time" ] } } }} ])

Cuyos rendimientos:

{ "_id" : ObjectId("532828ac338ed9c33aa8eca7"), "hour" : 11, "day" : 18, "month" : 3, "year" : 2014 }


Supongo que no hay forma de hacerlo. Porque el marco de agregación está escrito en código nativo. no haciendo uso del motor V8. Por lo tanto, todo lo relacionado con JavaScript no funcionará dentro del marco (y es por eso que el marco de agregación se ejecuta mucho más rápido).
Mapa / Reducir es una forma de resolver esto, pero el marco de agregación definitivamente obtuvo un rendimiento mucho mejor.

Acerca de Mapa / Reducir el rendimiento, lea este hilo .

Otra forma de resolverlo sería obtener un resultado "crudo" del marco de agregación, colocarlo en una matriz JSON. A continuación, realice la conversión ejecutando JavaScript. Algo así como:

var results = db.events.aggregate(...); reasult.forEach(function(data) { data.date = new Date(data.dateInMillionSeconds); // date is now stored in the "date" property }