MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Obtendo o timestamp unix em segundos do MongoDB ISODate durante a agregação


Não sei por que você acha que precisa do valor em segundos em vez de milissegundos, pois geralmente ambas as formas são válidas e, na maioria das implementações de linguagem, os milissegundos são realmente preferidos. Mas de um modo geral, tentar forçar isso em uma string é a maneira errada de contornar isso, e geralmente você apenas faz as contas:
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
        ]}
      ]
    }
  }}
])

O que retorna um timestamp de época em segundos. Basicamente derivado de quando um objeto de data BSON é subtraído de outro, o resultado é o intervalo de tempo em milissegundos. Usar a data de época inicial de "1970-01-01" resulta essencialmente na extração do valor de milissegundos do valor de data atual. A $divide O operador essencialmente retira a parte de milissegundos e o $mod faz o módulo para implementar o arredondamento.

Realmente, é melhor fazer o trabalho no idioma nativo do seu aplicativo, pois todas as datas BSON serão retornadas como um tipo nativo de "data/data e hora", onde você pode extrair o valor do carimbo de data/hora. Considere os fundamentos do JavaScript no shell:
var date = new Date()
( date.valueOf() / 1000 ) - ( ( date.valueOf() / 1000 ) % 1 )

Normalmente, com a agregação, você deseja fazer esse tipo de "matemática" para um valor de carimbo de data/hora para uso em algo como agregar valores em um período de tempo, como um dia. Existem operadores de data disponíveis para a estrutura de agregação, mas você também pode fazê-lo da maneira matemática de data:
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 }
    }}
])

Essa forma seria mais típica para emitir um timestamp arredondado para um dia e agregar os resultados dentro desses intervalos.

Portanto, seu propósito da estrutura de agregação apenas para extrair um carimbo de data/hora não parece ser o melhor uso ou, na verdade, não deve ser necessário convertê-lo em segundos em vez de milissegundos. No código do seu aplicativo é onde eu acho que você deveria fazer isso, a menos, é claro, que você realmente queira resultados para intervalos de tempo em que você possa aplicar a matemática de data conforme mostrado.

Os métodos estão lá, mas, a menos que você esteja realmente agregando, essa seria a pior opção de desempenho para seu aplicativo. Em vez disso, faça a conversão em código.