I’m using the go driver. Some of these issues are likely due to the go driver, but I believe the bulk is due to the API itself.
Here’s some inconsistencies:
type MyStruct struct {
Field1 map[string]struct{}
Field2 []string
Index int
Field4 SomeOtherStruct
}
// this works, however using $inc instead of set does not work. That's ok, I can deal.
collection.UpdateOne(ctx, bson.M{"id": id, "version": version}, mongo.Pipeline{
{{Key: "$set", Value: bson.M{"index": 3}}},
{{Key: "$addFields",
Value: bson.M{
"field2": bson.M{
"$arrayElemAt": []interface{}{"$field2", "$index"},
},
},
}},
})
// A little frustrating I can't use $index here, but again I'll live.
collection.UpdateOne(ctx, bson.M{"id": id}, bson.D{
{Key: "$set", Value: MyStruct{}}, {Key: "$push", Value: bson.M{
"field2": bson.M{
"$each": myStringArray,
"$position": "$index", // can't lookup the index here
},
}})
// But wait, I can't use the struct in a pipeline?!? (Hint: it complains about empty fields). Ok, starting to reconsider using mongo now...
collection.UpdateOne(ctx, bson.M{"id": id, "version": version}, mongo.Pipeline{
{{Key: "$set", MyStruct{}}}, // doesn't like the empty fields here.
{{Key: "$addFields",
Value: bson.M{
"field2": bson.M{
"$arrayElemAt": []interface{}{"$field2", "$index"},
},
},
}},
})
And there’s no fix! I can’t use addFields, or set with a lookup on arrayElemAt outside of the pipeline, and I can’t use set with the struct that may have empty fields in a pipeline.
Doing 2 queries to accomplish this is not even the frustrating part. The frustrating part is the lack of documentation around what is allowed to be strung together under what circumstances. Maybe I’ll understand it more with time. But API design is important, and it’s clear there is room for improvement here