sql >> Databasteknik >  >> NoSQL >> MongoDB

Få unix tidsstämpel på några sekunder från MongoDB ISODate under aggregering

Jag är inte säker på varför du tror att du behöver värdet i sekunder snarare än millisekunder eftersom i allmänhet båda formerna är giltiga och inom de flesta språkimplementeringar är millisekunderna faktiskt att föredra. Men generellt sett, att försöka tvinga detta till en sträng är fel sätt att gå runt det här, och i allmänhet räknar du bara:

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
        ]}
      ]
    }
  }}
])

Vilket ger dig en epoktidsstämpel på några sekunder. I grund och botten härleds från när ett BSON-datumobjekt subtraheras från ett annat så är resultatet tidsintervallet i millisekunder. Att använda det initiala epokdatumet "1970-01-01" resulterar i att i huvudsak extrahera millisekundersvärdet från det aktuella datumvärdet. $divide operatorn tar i princip bort millisekundersdelen och $mod gör modulo för att implementera avrundning.

Verkligen även om du är bättre av att göra arbetet på modersmålet för din applikation eftersom alla BSON-datum kommer att returneras dit som en inbyggd "datum/datumtid"-typ där du kan extrahera tidsstämpelvärdet. Tänk på grunderna i JavaScript i skalet:

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

Vanligtvis med aggregering vill du göra den här typen av "matte" till ett tidsstämpelvärde för användning i något som att aggregera värden inom en tidsperiod som en dag. Det finns datumoperatorer tillgängliga för aggregeringsramverket, men du kan också göra det på datummatematiken:

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 }
    }}
])

Det formuläret skulle vara mer typiskt att sända ut en tidsstämpel avrundad till en dag och aggregera resultaten inom dessa intervall.

Så ditt syfte med aggregeringsramverket bara för att extrahera en tidsstämpel verkar inte vara den bästa användningen eller det borde faktiskt inte vara nödvändigt att konvertera detta till sekunder snarare än millisekunder. I din ansökningskod är det där jag tycker att du bör göra det såvida du naturligtvis inte vill ha resultat för tidsintervall där du kan tillämpa datummatematiken som visas.

Metoderna finns där, men om du inte faktiskt aggregerar skulle detta vara det sämsta prestandaalternativet för din applikation. Gör konverteringen i kod istället.




  1. Hur man använder mongoose findOne

  2. Hur frågar jag efter distinkta värden i Mongoose?

  3. MongoDB-prestanda med växande datastruktur

  4. Redis prestanda på en multi-core CPU