varios tipos registro modificar insertar documentos documento datos data mongodb mongodb-query aggregation-framework

tipos - Conversión del tipo de datos en MongoDB



mongodb modificar documento (5)

PARA MONGO> = 3.0 (después de ~ 2015)

En caso de que algunas almas pobres tropiecen con esta pregunta en 2017, como yo: a partir de Mongo 3.0, ahora hay disponible un operador dateToString

lo que significa que si tienes la Fecha () adecuada, deberías poder hacer simplemente:

db.Document.aggregate( , {$project: {_id:1, CreationDate:1} , {$group: { _id : { $dateToString: { format: "%Y-%m-$d", date: "$CreationDate" } }, cnt:{$sum:1}}} , {$sort:{''cnt'':-1}} );

Para aquellos de nosotros que tienen fechas almacenadas en el campo sin fecha (¡qué alegría!), Puede crear un nuevo objeto Date () en el paso del proyecto. En mi caso, la fecha se almacenó como un número de milisegundos (entero) y agregué el número de milisegundos a la 0-Fecha.

db.Document.aggregate( , {$project: { _id:1, CreationDate: {"$add": [ new Date(0), "$CreatedOn" ]} } , {$group: { _id : { $dateToString: { format: "%Y-%m-$d", date: "$CreationDate" } }, cnt:{$sum:1}}} , {$sort:{''cnt'':-1}} );

Tengo una colección llamada Document in MongoDB. Los documentos en esta colección tienen un campo llamado CreationDate almacenado en tipo de fecha ISO. Mi tarea es contar la cantidad de documentos creados por día y ordenarlos por el número de forma asíncrona. El formato de salida debe ser [{_id: ''aaaa-MM-dd'', cnt: x}]. Traté de usar el marco de agregación de la siguiente manera.

db.Document.aggregate( , {$project: {_id:1, Year:{$year:''$CreationDate''}, Month:{$month:''$CreationDate''}, Date:{$dayOfMonth:''$CreationDate''}}} , {$group: {_id:{$concat:[''$Year'', ''-'', ''$Month'', ''-'', ''$Date'']}, cnt:{$sum:1}}} , {$sort:{''cnt'':-1}} );

El código me da un error como el siguiente:

$concat only supports strings, not NumberInt32

Entiendo que esto se debe a $ year, $ month y $ dayOfMonth todo el número de devolución. Es posible componer el campo _id como un objeto y volver a formatearlo en el formato deseado en el nivel de aplicación.

Pero desde una perspectiva técnica, tengo dos preguntas:

  1. ¿Cómo convertir un número a cadena en el shell MongoDB? En este caso, la producción de $ año puede convertirse a cadena y usarse en $ concat.

  2. ¿Hay una mejor manera de formatear la salida de ISODate a varios formatos de fecha? En muchos casos, solo necesitamos cierta parte de un ISODate, por ejemplo: el componente de fecha o la porción de tiempo. ¿Hay operadores incorporados de MongoDb para lograr esto?

Gracias de antemano por cualquier consejo.


La respuesta de Neil es correcta hasta el punto, pero tiene un pequeño error. En los condicionales (para verificar si el número del mes y el día debe ir precedido de un 0) no es $gt sino $lte .

Con $lte , solo los meses y días con un dígito se anteponerán con 0.

ej .: 2014-10- 0 3, 2014- 0 8- 0 3.


Otra forma más fácil de convertir ISODate a varios formatos de fecha es usar el operador de agregación $ dateToString .

db.collection.aggregate([ { $group: { _id: { $dateToString: { format: "%Y-%m-%d %H:%M", date: "$CreationDate" } }, count: { $sum: 1 } }}, { $sort : { count: -1 }} ])


Para convertir el formato de fecha a "xxxx-xx-xx"

db.getCollection(''analytics'').aggregate([ {$project: { day: {$dayOfMonth: "$createdAt"}, month: {$month: "$createdAt"}, year: {$year: "$createdAt"}, } }, {$project: { day: {$concat:["0", {$substr:["$day",0, 2]}]}, month: {$concat:["0", {$substr:["$month",0, 2]}]}, year: {$substr:["$year",0, 4]}, } }, {$project: {date: {$concat: [{$substr:["$year",0, 4]},"-", {$substr:["$month",0, 2]},"-", {$substr:["$day",0, 2]}]}}}, ]);


Puede hacer esto con $concat pero primero necesita convertir a una cadena a través de $substr , también manejando el caso de doble dígito:

db.Document.aggregate([ { "$group": { "_id":{ "$concat": [ { "$substr": [ { "$year": "$CreationDate" }, 0, 4 ] }, "-", { "$cond": [ { "$gt": [ { "$month": "$CreationDate" }, 9 ] }, { "$substr": [ { "$month": "$CreationDate" }, 0, 2 ] }, { "$concat": [ "0", { "$substr": [ { "$month": "$CreationDate" }, 0, 1 ] }, ]}, ]}, "-", { "$cond": [ { "$gt": [ { "$dayOfMonth": "$CreationDate" }, 9 ] }, { "$substr": [ { "$dayOfMonth": "$CreationDate" }, 0, 2 ] }, { "$concat": [ "0", { "$substr": [ { "$dayOfMonth": "$CreationDate" }, 0, 1 ] }, ]} ]} ] }, { "cnt": { "$sum": 1 } } }} { "$sort":{ "cnt" :-1 }} ]);

Posiblemente sea mejor utilizar solo las fechas matemáticas, esto devuelve un valor de marca de tiempo epoch, pero es fácil trabajar en un objeto de fecha en el procesamiento posterior:

db.Document.aggregate([ { "$group": { "_id": { "$subtract": [ { "$subtract": [ "$CreationDate", new Date("1970-01-01") ] }, { "$mod": [ { "$subtract": [ "$CreationDate", new Date("1970-01-01") ] }, 1000 * 60 * 60 * 24 ]} ] }, "cnt": { "$sum": 1 } }}, { "$sort": { "cnt": -1 } } ])