猿问

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

我在 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

}


holdtom
浏览 145回答 1
1回答

智慧大石

首先,使用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。
随时随地看视频慕课网APP

相关分类

Go
我要回答