Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Dapatkan kiraan item untuk setiap tarikh pada agregat MongoDB

Dapatkan kiraan item untuk setiap tarikh pada agregat MongoDB

王林
王林ke hadapan
2024-02-06 10:36:04413semak imbas

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

Kandungan soalan

Saya ada koleksi yang mengandungi acara. Setiap peristiwa mempunyai cap masa yang tepat hingga milisaat. Saya ingin mengumpulkan acara harian. Contohnya:

Saya ada

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

Saya buat

key        value

date       04-22-2023
count      1.0

date       04-23-2023
count      2.0

Matlamat utama adalah untuk menggunakan pertanyaan dalam projek golang.

Setakat ini saya ada

[
        {
            "$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
                }
            }
        }
    ]

Kembali

key            value

_id            04-24-2023
count          476.0

_id            04-23-2023
count          28.0

Ini sepatutnya berfungsi, tetapi apabila saya menulis pertanyaan ini dalam projek go saya, garis berlekuk merah muncul di bawah "$datetostring" dengan mesej "Nama medan tidak sah", idealnya saya ingin tarikh itu mempunyai kunci "masa" bukannya "_id". Apabila saya membuat perubahan berikut semasa peringkat kumpulan:

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

Saya mendapat ralat '$datetostring' pengendali kumpulan yang tidak diketahui. Jadi saya terfikir untuk mencipta kumpulan dan kemudian menambah peringkat item untuk "$datetostring" tetapi kini peringkat kumpulan mengembalikan kumpulan setiap milisaat yang mengalahkan tujuan pengumpulan.

Saya sedar saya sedang membincangkan dua isu berbeza. Walau bagaimanapun, walaupun sebarang bantuan adalah bagus, soalan ini adalah khusus tentang membetulkan pertanyaan mongo. Saya akan kembali ke pengekodan golang pada thread lain jika perlu. Jika saya boleh membuatnya lebih jelas, sila beritahu saya.


Jawapan betul


Pertama sekali, jika anda mempunyai ui aplikasi untuk memaparkan hasil pertanyaan, anda tidak perlu bersusah payah memformat output dalam pertanyaan. Ini adalah tanggungjawab ui aplikasi. BTW, jika anda mempunyai ui apl, pertimbangkan untuk menggunakan $datetrunc 而不是 $datetostring.

Bagaimanapun, mengenai keperluan dalam soalan anda, peringkat $project seperti ini sepatutnya sesuai untuk anda:

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

keluaran cangkerang mongodb:

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

Berkenaan menggunakan pertanyaan dalam projek go, berikut ialah demo:

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

Atas ialah kandungan terperinci Dapatkan kiraan item untuk setiap tarikh pada agregat MongoDB. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam