I’ve run into the following problem:
I want to facet my search results by some duration that I store in weeks in a numeric field. But I am having issues decoding the bucket results to a proper go type. The issue is that mongodb returns both number and string in the buckets array for numeric facets, and I cannot
My facet definition looks like the following:
var facets = bson.M{
// ...
"duration": bson.M{
"type": "number",
"path": "durationInWeeks",
"boundaries": bson.A{0, 52, 104, 156, 208},
"default": "208", // can't set int default; setting string causes problems in decoding. go fml :(
},
// ...
}
My aggregation looks like the following. The call to cursor.All
errors here.
// Now run a separate searchMeta to get the counts
searchStageForCount := bson.D{{"$searchMeta", bson.M{
"index": "my_index",
"facet": bson.M{
"facets": facets,
"operator": bson.D{
{"compound", getAllClauses(req)},
},
},
}}}
// run pipeline
cursor, err := collection.Aggregate(ctx, mongo.Pipeline{searchStageForCount})
if err != nil {
return nil, "", err
}
var resultsForCount []ResultMeta
if err = cursor.All(ctx, &resultsForCount); err != nil {
log.Println("debug: ", err.Error()) // this is failing currently
return nil, "", err
}
//
I experiemented with various types for ID. My ResultMeta
struct and its associated types are as follows:
type ResultMeta struct {
Count CountOption `bson:"count"`
Facet FacetOptions `bson:"facet"`
}
type FacetOptions struct {
// ...
duration SomeBuckets `bson:"duration" `
// ...
}
type SomeBuckets struct { Buckets []SomeBucket `bson:"buckets"`}
type SomeBucket {
ID int32 `bson:"_id"` // int variation, best case, need to omit "default" bucket
// ID primitive.ObjectID `bson:"_id"` // fails for int keys... cannot convert int32 to object id
// ID string `bson:"_id"` // string variation, ... cannot convert int32 to string
Count int32 `bson:"count"`
}
// ...
Is there any way to get around this?