首頁  >  文章  >  後端開發  >  檢索 MongoDB 聚合上每個日期的項目計數

檢索 MongoDB 聚合上每個日期的項目計數

王林
王林轉載
2024-02-06 10:36:04375瀏覽

检索 MongoDB 聚合上每个日期的项目计数

問題內容

我有一個包含事件的集合。每個事件都有精確到毫秒的時間戳記。我想將每天的事件分組。 例如:

我有

key       value

_id       111222333444555ddd666fff
time      2023-04-23t15:35:19.631z
type      pizza-event

_id       111222333444555ddd666fff
time      2023-04-23t01:41:20.631z
type      tv-event

_id       111222333444555ddd666fff
time      2023-04-22t05:00:05.631z
type      some-event

我願意

key        value

date       04-22-2023
count      1.0

date       04-23-2023
count      2.0

最終目標是在 golang 專案中使用查詢。

到目前為止我已經

[
        {
            "$match" : {
                "$and" : [
                    {
                        "type" : "foo.bar.event"
                    },
                    {
                        "time" : {
                            "$gte" : isodate("2023-04-23t00:00:00.000+0000")
                        }
                    },
                    {
                        "time" : {
                            "$lte" : isodate("2023-04-25t00:00:00.000+0000")
                        }
                    }
                ]
            }
        }, 
        {
            "$group" : {
                "_id" : {
                    "$datetostring" : {
                        "format" : "%m-%d-%y",
                        "date" : "$time"
                    }
                },
                "count" : {
                    "$sum" : 1.0
                }
            }
        }
    ]

返回

key            value

_id            04-24-2023
count          476.0

_id            04-23-2023
count          28.0

這本來可以工作,但是當我在go 專案中編寫此查詢時,“$datetostring”下會出現紅色波浪線,並顯示訊息“無效的欄位名稱”,理想情況下我希望日期有一個“時間”鍵而不是“_id”。當我在小組賽階段進行以下更改:

{
    _id: null,
    "date": {"$dateToString": { "format": "%m-%d-%Y", "date": "$time"}},
    "count": {"$sum": 1}
}

我收到未知群組運算子「$datetostring」錯誤。因此,我想到建立群組,然後為「$datetostring」新增一個專案階段,但現在小組階段每毫秒都會返回群組,這違背了分組的目的。

我意識到我正在討論兩個不同的問題。然而,雖然一切方面的幫助都會很棒,但這個問題具體是關於修復 mongo 查詢的。如果有必要,我會在另一個線程上返回 golang 編碼。 如果我能說得更清楚,請告訴我。


正確答案


首先,如果您有一個應用程式 ui 來顯示查詢結果,則不必費心格式化查詢中的輸出。這是應用程式 ui 的職責。順便說一句,如果您有應用程式 ui,請考慮使用 $datetrunc 而不是 $datetostring

無論如何,關於您問題中的要求,像這樣的 $project 階段應該適合您:

[
  {
    "$group": {
      "_id": {
        "$datetostring": { "date": "$time", "format": "%m-%d-%y" }
      },
      "count": { "$sum": 1 }
    }
  },
  { "$project": { "_id": 0, "time": "$_id", "count": "$count" } }
]

mongodb shell 的輸出:

{ "time" : "02-08-2020", "count" : 2 }
{ "time" : "05-18-2020", "count" : 2 }
{ "time" : "03-20-2021", "count" : 3 }
{ "time" : "01-11-2021", "count" : 1 }

關於在go專案中使用查詢,這裡有一個示範:

package main

import (
    "context"
    "fmt"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
    defer cancel()
    client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        panic(err)
    }

    coll := client.Database("baz").Collection("cakeSales")

    matchStage := bson.D{
        {"$match", bson.D{
            {"$and", []bson.D{
                {{"time", bson.D{
                    {"$gte", time.Date(2019, 6, 1, 0, 0, 0, 0, time.UTC)},
                }}},
                {{"time", bson.D{
                    {"$lte", time.Date(2021, 2, 1, 0, 0, 0, 0, time.UTC)},
                }}},
            }},
        }},
    }

    groupStage := bson.D{
        {"$group", bson.D{
            {"_id", bson.D{
                {"$dateToString", bson.D{
                    {"date", "$time"},
                    {"format", "%m-%d-%Y"},
                }},
            }},
            {"count", bson.D{
                {"$sum", 1},
            }},
        }},
    }

    projectStage := bson.D{
        {"$project", bson.D{
            {"_id", 0},
            {"time", "$_id"},
            {"count", "$count"},
        }},
    }

    cursor, err := coll.Aggregate(context.TODO(),
        mongo.Pipeline{matchStage, groupStage, projectStage})
    if err != nil {
        panic(err)
    }

    var results []bson.M
    if err = cursor.All(context.TODO(), &results); err != nil {
        panic(err)
    }
    for _, result := range results {
        fmt.Printf(
            "time: %s count: %v\n",
            result["time"],
            result["count"])
    }
}

以上是檢索 MongoDB 聚合上每個日期的項目計數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除