Maison >développement back-end >Golang >Récupérer le nombre d'éléments pour chaque date sur l'agrégat MongoDB

Récupérer le nombre d'éléments pour chaque date sur l'agrégat MongoDB

王林
王林avant
2024-02-06 10:36:04427parcourir

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

Contenu des questions

J'ai une collection contenant des événements. Chaque événement a un horodatage précis à la milliseconde près. Je souhaite regrouper les événements quotidiens. Par exemple :

J'ai

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

Oui

key        value

date       04-22-2023
count      1.0

date       04-23-2023
count      2.0

Le but ultime est d'utiliser des requêtes dans des projets Golang.

Jusqu'à présent, je l'ai fait

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

Retour

key            value

_id            04-24-2023
count          476.0

_id            04-23-2023
count          28.0

Cela était censé fonctionner, mais lorsque j'écris cette requête dans mon projet go, une ligne rouge ondulée apparaît sous "$datetostring" avec le message "Nom de champ invalide", idéalement j'aimerais que la date ait une clé "heure" au lieu de "_id". Quand j'ai effectué les changements suivants lors de la phase de groupes :

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

Je reçois une erreur d'opérateur de groupe inconnu '$datetostring'. J'ai donc pensé à créer le groupe, puis à ajouter une étape d'élément pour "$datetostring", mais maintenant l'étape de groupe renvoie le groupe toutes les millisecondes, ce qui va à l'encontre de l'objectif du regroupement.

Je me rends compte que je discute de deux problèmes différents. Cependant, même si toute aide serait précieuse, cette question concerne spécifiquement la correction des requêtes mongo. Je reviendrai au codage golang sur un autre fil si nécessaire. Si je peux être plus clair, faites-le-moi savoir.


Bonne réponse


Tout d'abord, si vous disposez d'une interface utilisateur d'application pour afficher les résultats de la requête, vous n'avez pas à vous soucier de formater la sortie dans la requête. C’est la responsabilité de l’interface utilisateur de l’application. BTW, si vous avez une interface utilisateur d'application, pensez à utiliser $datetrunc 而不是 $datetostring.

Quoi qu'il en soit, concernant les exigences de votre question, une $project étape comme celle-ci devrait fonctionner pour vous :

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

sortie du shell 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 }

Concernant l'utilisation des requêtes dans les projets go, voici une démo :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer