簡體   English   中英

Mongodb組收集時間戳記每天的時間戳,性能優化

[英]Mongodb group collection entries by day from timestamp, performance optimisation

我有一個使用mongodb存儲數據的Node Web應用程序。 我有一個類似於以下內容的消息集合:

[
  {
    "message": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut",
    "pubDate": "2014-01-16T14:15:33.792Z",
    "pubTimezone": "America/Tijuana"
    "id": "a9baa2f0-7eb8-11e3-b732-0b0c79e81098"
  },
  {
    "message": "labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco",
    "pubDate": "2014-01-16T14:01:24.198Z",
    "pubTimezone": "America/Tijuana"
    "id": "af550860-7eb6-11e3-b732-0b0c79e81098"
  },
  {
    "message": "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in",
    "pubDate": "2014-01-17T01:12:27.277Z",
    "pubTimezone": "America/Tijuana"
    "id": "6dff53d0-7f14-11e3-b732-0b0c79e81098"
  },
  {
    "message": "voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat",
    "pubDate": "2014-01-17T01:10:17.249Z",
    "pubTimezone": "America/Tijuana"
    "id": "207ea110-7f14-11e3-b732-0b0c79e81098"
  }
...
]

我想運行一個查詢,該查詢根據pubDate時間戳按天分組,從而產生輸出:

[
  {
    "items":[
      {
        "message":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut",
        "pubDate":"2014-01-16T14:15:33.792Z",
        "pubTimezone": "America/Tijuana"
        "id":"a9baa2f0-7eb8-11e3-b732-0b0c79e81098"
      },
      {
        "message":"labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco",
        "pubDate":"2014-01-16T14:01:24.198Z",
        "pubTimezone": "America/Tijuana"
        "id":"af550860-7eb6-11e3-b732-0b0c79e81098"
      }
    ],
    "day":"2014-01-16T00:00:00.000Z"
  },
  {
    "items":[
      {
        "message":"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in",
        "pubDate":"2014-01-17T01:12:27.277Z",
        "pubTimezone": "America/Tijuana"
        "id":"6dff53d0-7f14-11e3-b732-0b0c79e81098"
      },
      {
        "message":"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat",
        "pubDate":"2014-01-17T01:10:17.249Z",
        "pubTimezone": "America/Tijuana"
        "id":"207ea110-7f14-11e3-b732-0b0c79e81098"
      }
    ],
    "day":"2014-01-17T00:00:00.000Z"
  }
...
]

如果訂購了反向日期日期順序,則必須使用時區來計算日期。 結果分頁,每頁50條。
請注意,有些日子沒有創建任何項目,並且db中的pubDates均為ISODate格式。

我已經閱讀了一些有關分組的文章,但是它們似乎都在執行求和/計數任務,而不是按照我想要的輸出格式按天對所有結果進行分組。 我還閱讀了一些有關聚合框架和map的博客文章 ,這些文章減少了但進展不大。

如果有可能在同一查詢中獲得total_messages和total_days,那就太好了,盡管當我得到結果時,我總是可以在代碼中做到這一點。

我的網絡應用程序的工作方式是,它按日期先后順序提取所有消息,然后按代碼對它們進行按天排序,而且性能相當糟糕,所以我希望找到一種方法來處理數字,因為數據是從數據庫中出來。

任何指導和/或幫助,不勝感激。

如果日期采用ISODate格式,則應將其保存為此類型在數據庫中。 以下行顯示類型是字符串:

    "pubDate": "2014-01-16T14:15:33.792Z",

它看起來應該像這樣:

{
  "message" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut",
  "pubDate" : ISODate("2014-01-16T14:15:33.792Z"),
  "pubTimezone" : "America/Tijuana",
  "id" : "a9baa2f0-7eb8-11e3-b732-0b0c79e81098"
}

在第一個建議中,假設您可以將字符串更改為ISODate類型。 然后,您可以使用聚合框架功能提取有關日期的信息。 MongoDB將返回與GMT-0值相對應的年,月和日的值。 我認為這是您想要的,但如果沒有,請參閱第二種解決方案。

然后,運行聚合查詢將為您提供所需的信息:

db.mycollection.aggregate([{"$project":{year:{"$year":"$pubDate"},month:{"$month":"$pubDate"},day:{"$dayOfMonth":"$pubDate"},"item":{"message":"$message","pubDate":"$pubDate","pubTimezone":"$pubTimezone","id":"$id"}}},{"$group":{"_id":{"year":"$year","month":"$month","day":"$day"},"items":{"$push":"$item"},"count":{"$sum":1}}}]).result

[
{
    "_id" : {
        "year" : 2014,
        "month" : 1,
        "day" : 17
    },
    "items" : [
        {
            "message" : "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in",
            "pubDate" : ISODate("2014-01-17T01:12:27.277Z"),
            "pubTimezone" : "America/Tijuana",
            "id" : "6dff53d0-7f14-11e3-b732-0b0c79e81098"
        },
        {
            "message" : "voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat",
            "pubDate" : ISODate("2014-01-17T01:10:17.249Z"),
            "pubTimezone" : "America/Tijuana",
            "id" : "207ea110-7f14-11e3-b732-0b0c79e81098"
        }
    ],
    "count" : 2
},
{
    "_id" : {
        "year" : 2014,
        "month" : 1,
        "day" : 16
    },
    "items" : [
        {
            "message" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut",
            "pubDate" : ISODate("2014-01-16T14:15:33.792Z"),
            "pubTimezone" : "America/Tijuana",
            "id" : "a9baa2f0-7eb8-11e3-b732-0b0c79e81098"
        },
        {
            "message" : "labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco",
            "pubDate" : ISODate("2014-01-16T14:01:24.198Z"),
            "pubTimezone" : "America/Tijuana",
            "id" : "af550860-7eb6-11e3-b732-0b0c79e81098"
        }
    ],
    "count" : 2
}
]

請注意,您只能對一個字段列表進行分組。 這意味着,您可以獲取每天的文檔計數,將聚合返回的文檔數量用作您的天數,但是您將需要計算應用程序中的消息總數,並遍歷文檔。

對於您無法使用ISODate類型或想要在非GMT時間存儲數據的情況的第二種解決方案。 在該解決方案中,計算一個附加字段,該字段代表要匯總的日期。 例如,您將使用附加的“日期”字段創建文檔:

{
  "message" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut",
  "pubDate" :"2014-01-16T14:15:33.792Z",
  "pubTimezone" : "America/Tijuana",
  "date" : "2014-01-16"),
  "id" : "a9baa2f0-7eb8-11e3-b732-0b0c79e81098"
}

然后編寫一個類似的聚合查詢,但是在$ group子句中使用'date'作為您的'_id'。 使用預先計算的字段進行匯總的優點是它會更快,但也可以讓您做一個簡單的

find({"date":"2014-01-16"})

查詢以檢索文檔的子集(如果需要)。 與聚合框架相比,使用簡單的find()命令的一個優勢是后者需要在返回結果之前完成所有處理。 find()命令將開始批量返回結果,因此,如果您打算將結果分頁給用戶,則速度更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM