我正在try 用Golang语言(下面我附上了纯MongoDB查询的工作代码)使用go.mongodb.org/mongo-driver/mongo库进行查询,下面是Golang查询代码.我无法让matchStage正常工作,我已经try 了许多变种,我肯定我只是非常粗心或只是不理解

我怎样才能同时用$match$expr$and$lte算出正确的matchStage呢?

func (r *Mongo) ChatHistory(ctx context.Context, chatID string, f *Filter) ([]*Message, error) {
    matchStage := bson.D{
        primitive.E{
            Key: "$match",
            Value: bson.D{
                primitive.E{Key: "$expr", Value: bson.D{
                    primitive.E{Key: "$and", Value: bson.A{
                        bson.D{
                            primitive.E{Key: "$lte", Value: bson.D{
                                primitive.E{
                                    Key:   "$create_date",
                                    Value: f.Date, // int64
                                },
                            }},
                        },
                    }},
                }},
            },
        },
    }
    sortStage := bson.D{
        {
            Key: "$sort", Value: bson.D{
                primitive.E{Key: "create_date", Value: -1},
            },
        },
    }
    limitStage := bson.D{primitive.E{Key: "$limit", Value: f.Count}}

    cursor, err := r.colMessage.Aggregate(ctx, mongo.Pipeline{matchStage, sortStage, limitStage})
    if err != nil {
        l.Error().Err(err).Msg("failed find")
        return nil, err
    }

    var res []*Message
    if err = cursor.All(ctx, &res); err != nil {
        l.Error().Err(err).Msg("failed find all documents")
        return nil, err
    }

    if err = cursor.Close(ctx); err != nil {
        l.Error().Err(err).Msg("failed close cursor")
        return nil, err
    }

    return res, nil
}

Error:(InvalidPipelineOperator) Unrecognized expression '$create_date'

MongoDB playground link

推荐答案

$lte必须是数组而不是文档:

matchStage := bson.D{
    primitive.E{
        Key: "$match",
        Value: bson.D{
            primitive.E{Key: "$expr", Value: bson.D{
                primitive.E{Key: "$and", Value: bson.A{
                    bson.D{
                        primitive.E{Key: "$lte", Value: bson.A{
                            "$create_date",
                            f.Date, // int64
                        }},
                    },
                }},
            }},
        },
    },
}

还请注意,您可以从复合文本中省略primitive.E类型:

matchStage := bson.D{
    {
        Key: "$match",
        Value: bson.D{
            {Key: "$expr", Value: bson.D{
                {Key: "$and", Value: bson.A{
                    bson.D{
                        {Key: "$lte", Value: bson.A{
                            "$create_date",
                            f.Date, // int64
                        }},
                    },
                }},
            }},
        },
    },
}

但请注意,您在芒果操场上的表情是不正确的.引用doc人的话:

$match接受指定查询条件的文档.查询语法与read operation query语法相同 ...

当使用$expr时,您必须使用$eq,例如:

matchStage := bson.D{
    {
        Key: "$match",
        Value: bson.D{
            {Key: "$expr", Value: bson.D{
                {Key: "$and", Value: bson.A{
                    bson.D{
                        {Key: "$eq", Value: bson.A{
                            "$chat_id",
                            chatID,
                        }},
                    },
                    bson.D{
                        {Key: "$lte", Value: bson.A{
                            "$create_date",
                            f.Date, // int64
                        }},
                    },
                }},
            }},
        },
    },
}

在这里试试:https://mongoplayground.net/p/SBEJD-Fyhjl

您应该使用$match中的普通查询文档.

请参阅这个等效的、简单得多的解决方案:

matchStage := bson.D{
    {
        Key: "$match",
        Value: bson.D{
            {Key: "chat_id", Value: chatID},
            {Key: "create_date", Value: bson.D{
                {
                    Key:   "$lte",
                    Value: f.Date, // int64
                }},
            },
        },
    },
}

如果你用bson.M而不是bson.D,那就更简单了:

matchStage := bson.M{
    "$match": bson.M{
        "chat_id":     chatID,
        "create_date": bson.M{"$lte": f.Date},
    },
}

当然,在最后一种情况下,您不能将mongo.Pipeline用于管道,但[]any[]bson.M也可以.

Mongodb相关问答推荐

MongoDB-如何过滤和获取数组字段中的最新数据

使用Go的Mongo驱动程序,从MongoDB文档中获取元素并更新其值需要帮助

Mongodb 按数组元素聚合组

聚合 $accumulator + $project

更新 Mongodb 中的多嵌套数组

mongoose中的 required是什么意思?

MongoDB聚合多条件

哪个库最适合用于带有 Scala 的 MongoDB?

无法使用机器 ip 连接到 mongodb

Mongo 无法启动

.save() 不是函数 Mongoose

如何使用 C# MongoDB 驱动程序检索字段子集?

Node.js 数据库的抽象层

Mongodb将重音字符匹配为基础字符

如何在 MongoDB 中进行内部连接?

使用 MongoDB 进行嵌套分组

使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

MongoDB Compass 过滤器(查询)

MongoDB:聚合框架: $match between fields

我可以只获取 Cursor 对象(pymongo)中的第一项吗?