I'm trying to make a query in golang language (below I've attached working code of pure mongodb query) using go.mongodb.org/mongo-driver/mongo library, below is golang query code. I can't get matchStage to work correctly, I've tried many variants and I'm sure I'm just very inattentive or just don't understand
How can I use $match, $expr, $and and $lte at once to make a correct 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'
Value of
$ltemust be an array not a document:Also note that you can leave out the
primitive.Etype from the composite literal:But note that your expression on the mongo playground is incorrect. Quoting from the doc:
When using
$expr, you have to use$eq, for example:Try it here: https://mongoplayground.net/p/SBEJD-Fyhjl
You should use a normal query document in
$match.See this equivalent, much simpler solution:
And even much-much simpler if you use
bson.Minstead ofbson.D:Of course in this last case you can't use
mongo.Pipelinefor the pipeline, but[]anyor[]bson.Mwould also do.