为了账号安全,请及时绑定邮箱和手机立即绑定

聚合管道返回错误结果与 CLI

聚合管道返回错误结果与 CLI

Go
holdtom 2023-06-12 15:41:46
我在 mongo 中有一个集合,我在上面运行以下查询db.feeds.aggregate({"$match":{createdat:"20190203"}}, {"$group": {_id: {"type": "$type"}, total: {$sum: 1} }},{"$project":   {"type": "$_id.type", "tot": "$total", "_id": 0} }   )它按预期工作并返回,{ "type" : "f", "tot" : 1 }{ "type" : "ebm", "tot" : 1 }{ "type" : "b", "tot" : 3 }但是,当我尝试在 Golang 中复制管道时,如下所示:    pipeline := []bson.M{    // match    {"$match": bson.M{"createdat": when}},    // group    {"$group": bson.M{        "_id":        bson.M{"type": "$type"}, // "$fieldname" - return the field        "TotalFeeds": bson.M{"$sum": 1}}},    // project    {"$project": bson.M{"type": "$_id.type", // project selects subset of fields        "TotalFeeds": "$TotalFeeds", // rename fiedls        "_id":        0}},           // 0 means not show _id}返回的计数为 0。map[$match:map[createdat:20190203]] map[$group:map[TotalFeeds:map[$sum:1] _id:map[type:$type]]] map[$project:map[type:$_id.type TotalFeeds:$TotalFeeds _id:0]]]{f 0  }{ebm 0  }{b 0  }[{f 0  } {ebm 0  } {b 0  }]下面是我在 Golang 中使用的整个函数:func CountFeeds(when string) Feeds {    ctx, _ := context.WithTimeout(context.Background(), 60*time.Second)    pipeline := []bson.M{        // match        {"$match": bson.M{"createdat": when}},        // group        {"$group": bson.M{            "_id":        bson.M{"type": "$type"}, // "$fieldname" - return the field            "TotalFeeds": bson.M{"$sum": 1}}},        // project        {"$project": bson.M{"type": "$_id.type", // project select subset of fields            "TotalFeeds": "$TotalFeeds", // rename fiedls            "_id":        0}},           // 0 means not show _id    }    fmt.Println(pipeline)    curs, err := db.Collection("feeds").Aggregate(ctx, pipeline)    utilities.Catch(err)    defer curs.Close(ctx)    element := Feeds{}    e := []Feeds{}    for curs.Next(ctx) {        err := curs.Decode(&element)        fmt.Println(element)        utilities.Catch(err)        e = append(e, element)    }    fmt.Println(e)    return element}
查看完整描述

1 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

首先,使用bson.D{}而不是bson.M{}。这是因为bson.D{}应该在顺序很重要的情况下使用,例如 MongoDB 命令。

您还可以将整个管道封装在mongo.Pipeline中。例如:

pipeline := mongo.Pipeline{

    {{"$match", bson.D{{"createdata", 10}}}},

    {{"$group", bson.D{

        {"_id",        bson.D{{"type", "$type"}}}, 

        {"TotalFeeds", bson.D{{"$sum", 1}}},

    }}},

    {{"$project", bson.D{

        {"type", "$_id.type"}, 

        {"TotalFeeds", "$TotalFeeds"}, 

        {"_id", 0}},

    }},          

}

检查你的Feeds{}结构映射。确保您指定映射bson,即:


type Feeds struct {

    Type string `bson:"type"`

    TotalFeeds int `bson:"TotalFeeds"`

}

或者,在您的投影阶段,$project您对字段使用一致的大小写。例如,指定所有小写type和/totalfeeds或所有大写Type和TotalFeeds。


pipeline := mongo.Pipeline{

    {{"$match", bson.D{{"createdata", 10}}}},

    {{"$group", bson.D{

        {"_id",        bson.D{{"type", "$type"}}}, 

        {"totalfeeds", bson.D{{"$sum", 1}}},

    }}},

    {{"$project", bson.D{

        {"type", "$_id.type"}, 

        {"totalfeeds", "$totalfeeds"}, 

        {"_id", 0}},

    }},      

}

然后你不必bson在结构中指定映射:


type MyStruct struct {

    Type string 

    Total int

}

因此,要么在结构中使用一致的字段名称大小写,要么显式提供映射bson。


查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信