sql >> Base de Datos >  >> NoSQL >> MongoDB

Obtener la marca de tiempo de Unix en segundos fuera de MongoDB ISODate durante la agregación

No estoy seguro de por qué cree que necesita el valor en segundos en lugar de milisegundos, ya que generalmente ambas formas son válidas y, en la mayoría de las implementaciones de lenguaje, se prefieren los milisegundos. Pero, en términos generales, tratar de forzar esto en una cadena es la forma incorrecta de evitarlo y, por lo general, solo haces los cálculos:

db.data.aggregate([
  { "$project": {
    "timestamp": {
      "$subtract": [
        { "$divide": [
            { "$subtract": [ "$md", new Date("1970-01-01") ] },
            1000
        ]},
        { "$mod": [
          { "$divide": [
              { "$subtract": [ "$md", new Date("1970-01-01") ] },
              1000
          ]},
          1
        ]}
      ]
    }
  }}
])

Lo que le devuelve una marca de tiempo de época en segundos. Básicamente derivado de cuando un objeto de fecha BSON se resta de otro, el resultado es el intervalo de tiempo en milisegundos. El uso de la fecha de época inicial de "1970-01-01" da como resultado esencialmente extraer el valor de milisegundos del valor de fecha actual. La $divide esencialmente quita la porción de milisegundos y el $mod hace el módulo para implementar el redondeo.

Realmente, aunque es mejor que haga el trabajo en el idioma nativo para su aplicación, ya que todas las fechas BSON se devolverán allí como un tipo nativo de "fecha/fechahora" donde puede extraer el valor de la marca de tiempo. Considere los conceptos básicos de JavaScript en el shell:

var date = new Date()
( date.valueOf() / 1000 ) - ( ( date.valueOf() / 1000 ) % 1 )

Por lo general, con la agregación, desea hacer este tipo de "matemáticas" con un valor de marca de tiempo para usar en algo como agregar valores dentro de un período de tiempo, como un día. Hay operadores de fecha disponibles para el marco de agregación, pero también puede hacerlo de la manera matemática de fecha:

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

Ese formulario sería más típico para emitir una marca de tiempo redondeada a un día y agregar los resultados dentro de esos intervalos.

Por lo tanto, su propósito del marco de agregación solo para extraer una marca de tiempo no parece ser el mejor uso o, de hecho, no debería ser necesario convertir esto a segundos en lugar de milisegundos. En el código de su aplicación es donde creo que debería hacerlo, a menos que, por supuesto, realmente desee resultados para intervalos de tiempo en los que pueda aplicar las matemáticas de fecha como se muestra.

Los métodos están ahí, pero a menos que realmente esté agregando, esta sería la peor opción de rendimiento para su aplicación. Haz la conversión en código en su lugar.