It would be awesome if there was a non-cludgy way to initialize timeseries collections. Creating a normal collection / handle is easy in golang and if it doesn’t exist, it gets created. It’s seamless. This isn’t the case with timeseries collections as far as I can tell. Here’s something terrible I hacked together:
var timeseriesMetricsName = "timeseries_metrics"
// Timeseries collections must be explicitly created so we explicitly create it here
err = Database.CreateCollection(ctx, timeseriesMetricsName, &options.CreateCollectionOptions{
TimeSeriesOptions: &options.TimeSeriesOptions{
TimeField: "created",
MetaField: aws.String("metadata"),
Granularity: aws.String("hours"),
}})
// If it already exists then we swallow that error, otherwise we panic on all others
if err != nil {
if !strings.HasPrefix(err.Error(), "(NamespaceExists) A timeseries collection already exists") {
log.Fatal(fmt.Sprintf("Error creating collection [%s]: [%+v]", timeseriesMetricsName, err))
} else {
fmt.Println(fmt.Sprintf("%s table already exists. continuing.", timeseriesMetricsName))
}
} else {
fmt.Println(fmt.Sprintf("Successfully created %s table for the first time.", timeseriesMetricsName))
}
Here’s a far less disgusting implementation but it’s still not pretty because golang doesn’t search arrays of strings well and you still have to handle a lot of errors.
A native driver function for CreateIfNotExist
would be awesome. Even better if the driver handled timeseries collections identically do regular collections and create if necessary otherwise return a handle to the existing collection.
Timeseries create if not exist code:
Database = Client.Database(Name)
var timeseriesMetricsName = "timeseries_metrics"
exists := false
names, err := Database.ListCollectionNames(ctx, bson.D{}, nil)
for _, name := range names {
if name == timeseriesMetricsName {
exists = true
fmt.Println(fmt.Sprintf("%s table already exists. continuing.", timeseriesMetricsName))
}
}
if !exists {
// Timeseries collections must be explicitly created so we explicitly create it here
err = Database.CreateCollection(ctx, timeseriesMetricsName, &options.CreateCollectionOptions{
TimeSeriesOptions: &options.TimeSeriesOptions{
TimeField: "created",
MetaField: aws.String("metadata"),
Granularity: aws.String("hours"),
}})
if err != nil {
log.Fatal(fmt.Sprintf("Error creating collection [%s]: [%+v]", timeseriesMetricsName, err))
} else {
fmt.Println(fmt.Sprintf("Successfully created %s table for the first time.", timeseriesMetricsName))
}
}
Regular collection create if not exist code:
AdminColl = Database.Collection("admins")
The difference here is huge.