To be clear, I’m trying to replicate this behavior: https://docs.mongodb.com/manual/core/index-unique/#unique-constraint-across-separate-documents.
I’m calling *mongo.Collection.Indexes().CreateOne with a mongo.IndexModel argument. My code is below. It errors on the second call to indexCollection (indexcnt == 1) with:
➜ ./mongo_test
2020/03/03 12:50:24 indexed the collection 1 time(s).
2020/03/03 12:50:24 failed to index DB: (IndexOptionsConflict) Inde
x with name: param3_1_param1_1_param2_1 already exists with a diffe
rent name
Ahh, so let me give this index a common name across my applications (and in this test code) to see if it doesn’t break.
I’m using mongo-go-driver v1.3.1 with go 1.14. My mongod version is
➜ ./bin/mongod -version
db version v4.2.2
git version: a0bbbff6ada159e19298d37946ac8dc4b497eadf
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_64
My code
package main
import (
"context"
"flag"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func main() {
flagURI := flag.String("uri", "mongodb://localhost:27017", "URI of the MongoDB host (e.g. mongodb://localhost:27017")
flag.Parse()
client, err := mongo.NewClient(options.Client().ApplyURI(*flagURI))
if err != nil {
log.Fatalf("failed to obtain a MongoDB client: %s", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
log.Fatalf("failed to connect to mongod: %s", err)
}
if err := client.Ping(ctx, readpref.Primary()); err != nil {
log.Fatalf("failed to ping mongod: %s", err)
}
db := client.Database("brand-new-db")
coll := db.Collection("brand-new-collection")
var indexcnt int
if err := indexCollection(coll); err != nil {
log.Printf("indexed the collection %d time(s).", indexcnt)
log.Fatalf("failed to index DB: %s", err)
}
indexcnt++
if err := indexCollection(coll); err != nil {
log.Printf("indexed the collection %d time(s).", indexcnt)
log.Fatalf("failed to index DB: %s", err)
}
}
func indexCollection(coll *mongo.Collection) error {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
t := true
_, err := coll.Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: map[string]int{
"param1": 1,
"param2": 1,
"param3": 1,
},
Options: &options.IndexOptions{
Unique: &t,
},
})
return err
}