首页 > 解决方案 > 如何做MongoDB聚合

问题描述

我正在尝试实现 mongodb 分页,这部分没问题,我得到了限制并跳过了数据,但是我想在不发出第二次请求的情况下获得我的元素的总数。

我使用聚合和管道来填充一些数据,因此需要使用聚合。

事实上,我想将我的 mongo 结果解码为:

type exemple struct {
    Orders []Order
    Total int
}

我不知道是否有可能没有提出两个请求我试图测试一些事情:

       bson.D{
                primitive.E{Key: "$facet", Value: bson.D{
                    primitive.E{Key: "orders", Value: []bson.D{
                        {primitive.E{Key: "$skip", Value: p.Skip}},
                        {primitive.E{Key: "$limit", Value: p.Limit}},
                    }},
                    primitive.E{Key: "totalCount", Value: []bson.D{
                        {primitive.E{Key: "$group", Value: bson.D{
                            primitive.E{Key: "_id", Value: nil},
                            primitive.E{Key: "count", Value: bson.D{
                                primitive.E{Key: "$sum", Value: 1},
                            }},
                        }}},
                    }},
                }},
            }

这项工作,但只解码:

    type exemple struct {
        Orders     []Order                  `bson:"orders" json:"orders"`
        TotalCount []map[string]interface{} `bson:"totalCount" json:"totalCount"`
    }

我必须用 [] 示例解码为:

var test []exemple
if err = curs.All(r.ctx, &test); err != nil {
    return err
}

所以为了得到我的数据,我必须做一些 fmt.Println(test[0].TotalCount) 这很可怕所以我认为有更好的方法..

而且我想我了解一个 $project 所以我想重新创建我的模式数据,但它太挑剔而且不是很好。

我也试过这个:

{primitive.E{Key: "$count", Value: "count"}},
{primitive.E{Key: "$skip", Value: p.Skip}},
{primitive.E{Key: "$limit", Value: p.Limit}},

但是这个尝试为每个数据提供一个计数键,其中包含我的数据库中的每个数据。

抱歉这个不清楚的问题我真的不知道如何正确解释这个问题,这可能是我找不到答案的原因。

- - - - - - - - - - - 编辑 - - - - - - - - - - -

经过测试,我发现一些工作,但如果有人有更好的解决方案,我正在听:

我将其添加到我的管道中:

       bson.D{
            primitive.E{Key: "$facet", Value: bson.D{
                primitive.E{Key: "orders", Value: []bson.D{
                    {primitive.E{Key: "$skip", Value: 10}},
                    {primitive.E{Key: "$limit", Value: 10}},
                }},
                primitive.E{Key: "totalCount", Value: []bson.D{
                    {primitive.E{Key: "$count", Value: "count"}},
                }},
            }},
        }

并将聚合函数的结果映射到:

resp := struct {
    Orders     []Order                  `bson:"orders" json:"orders"`
    TotalCount []map[string]interface{} `bson:"totalCount" json:"totalCount"`
}{}

我之前的错误是使用 cursor.All() 而不是 for 循环到 cursor.Next() 然后 decode(&resp) 进入循环:

for curs.Next(r.ctx) {
    if err = curs.Decode(&resp); err != nil {
        log.Println(err)
    }
}

现在我可以使用我的 resp,比如 resp.Orders 或 resp.TotalCount。

但是有些问题仍然存在:

输出:[map[count:5]],预期:map[count:5]

[]bson.D{
        {primitive.E{Key: "$lookup", Value: bson.D{primitive.E{Key: "from", Value: "users"}, primitive.E{Key: "localField", Value: "relationShip.customer"}, primitive.E{Key: "foreignField", Value: "_id"}, primitive.E{Key: "as", Value: "relationShip.included.customer"}}}},
        {primitive.E{Key: "$unwind", Value: bson.D{primitive.E{Key: "path", Value: "$relationShip.included.customer"}, primitive.E{Key: "preserveNullAndEmptyArrays", Value: false}}}},
        {primitive.E{Key: "$lookup", Value: bson.D{primitive.E{Key: "from", Value: "users"}, primitive.E{Key: "localField", Value: "relationShip.editor"}, primitive.E{Key: "foreignField", Value: "_id"}, primitive.E{Key: "as", Value: "relationShip.included.editor"}}}},
        {primitive.E{Key: "$unwind", Value: bson.D{primitive.E{Key: "path", Value: "$relationShip.included.editor"}, primitive.E{Key: "preserveNullAndEmptyArrays", Value: false}}}},
    }

这有效,但我在分页之前添加了这个,所以 mongodb 查找整个集合?是否可以在分页后添加它以提高性能?

标签: mongodbgoaggregation-framework

解决方案


推荐阅读