I am trying to get a list of data that match specific queries but I am getting this error
"(AtlasError) merchant is not allowed or the syntax is incorrect, see the Atlas documentation for more information"
func ...
var result []*model.Package
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
tokenData, err := middleware.CtxValue(ctx)
if err != nil {
return nil, err
}
orQuery := []bson.M{}
merchant := "abc"
completedQuery := bson.M{"status": "completed"}
cancelledQuery := bson.M{"status": "cancelled"}
orQuery = append(
orQuery,
cancelledQuery,
completedQuery)
limit64 := int64(limit)
page64 := int64(page)
match := bson.M{"$match": bson.M{"$nor": orQuery}}
var filterQuery primitive.M
if tokenData.Role == "admin" && merchant != nil {
filterQuery = bson.M{"merchant": bson.M{"id": merchant}}
} else {
filterQuery = bson.M{"user": bson.M{"id": tokenData.Id}}
}
paginatedData, err1 := paginate.New(r.Collection).Context(ctx).Limit(limit64).Page(page64).Aggregate(match, filterQuery)
if err1 != nil {
return nil, err1
}
...
CodePudding user response:
filterQuery
, which seems to contain { "merchant" : { "id" : "abc" } }
, is being passed sepearately to .Aggregate()
. But the aggregation framework is expecting to receive something that represents a sequence of pipeline stages. Each of these stages, outlined here in the documentation, are expected to begin with a $
character such as the $match
stage.
Currently the database is attempting to process merchant
as an options
for the pipeline (see here and here). But such an option doesn't exist, hence the error message.
To resolve this, you should incorporate the filterQuery
logic into the existing match
variable/stage that you are building and passing. Alternatively you can wrap filterQuery
in a different $match
and then pass both of them (as a single argument) to .Aggregate()
.
This example in the documentation shows they build multiple stages and then submit them together to .Aggregate()
via mongo.Pipeline{...}
:
// create the stages
matchStage := bson.D{{"$match", bson.D{{"toppings", "milk foam"}}}}
unsetStage := bson.D{{"$unset", bson.A{"_id", "category"}}}
sortStage := bson.D{{"$sort", bson.D{
{"price", 1},
{"toppings", 1}},
}}
limitStage := bson.D{{"$limit", 2}}
// pass the stage into a pipeline
// pass the pipeline as the second paramter in the Aggregate() method
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage})