From 5e70b5f9cbcf7bbb7feb80218ba84c2a2ad1a3d7 Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:49:35 -0500 Subject: [PATCH 1/8] fix prepareUnique --- common/idx/index_catalog.go | 4 - mongodump/oplog_dump_test.go | 152 +++++++++++++++++++++++++++++++++-- mongorestore/oplog_test.go | 48 +++++++++++ 3 files changed, 195 insertions(+), 9 deletions(-) diff --git a/common/idx/index_catalog.go b/common/idx/index_catalog.go index 3cbd9d8e9..b03cbaba9 100644 --- a/common/idx/index_catalog.go +++ b/common/idx/index_catalog.go @@ -368,10 +368,6 @@ func (i *IndexCatalog) collMod(database, collection string, indexModValue any) e updateHidden(matchingIndex, newHidden) } - if expireKeyError != nil && hiddenKeyError != nil { - return errors.Errorf("must specify expireAfterSeconds or hidden: %v", indexMod) - } - // Update the index. i.AddIndex(database, collection, matchingIndex) return nil diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index f11f445b4..92fc7ab96 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -8,12 +8,8 @@ package mongodump import ( "context" - "io" - "os" - "path/filepath" - "testing" - "github.com/mongodb/mongo-tools/common/bsonutil" + "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/failpoint" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/testtype" @@ -22,7 +18,12 @@ import ( . "github.com/smartystreets/goconvey/convey" "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" + "io" + "os" + "path/filepath" + "testing" ) func TestErrorOnImportCollection(t *testing.T) { @@ -131,3 +132,144 @@ func vectoredInsert(ctx context.Context) error { return nil } + +func TestOplogDumpCollModPrepareUnique(t *testing.T) { + testtype.SkipUnlessTestType(t, testtype.IntegrationTestType) + + ctx := t.Context() + + session, err := testutil.GetBareSession() + if err != nil { + t.Fatalf("Failed to get session: %v", err) + } + fcv := testutil.GetFCV(session) + if cmp, err := testutil.CompareFCV(fcv, "6.0"); err != nil || cmp < 0 { + if err != nil { + t.Errorf("error getting FCV: %v", err) + } + t.Skipf("Requires server with FCV 6.0 or later; found %v", fcv) + } + + testCollName := testCollectionNames[0] + + err = session.Database(testDB).CreateCollection(ctx, testCollName) + require.NoError(t, err) + //nolint:errcheck + defer session.Database(testDB).Collection(testCollName).Drop(ctx) + + md, err := simpleMongoDumpInstance() + require.NoError(t, err) + + md.ToolOptions.DB = "" + md.OutputOptions.Oplog = true + md.OutputOptions.Out = "collMod_prepareUnique" + + require.NoError(t, md.Init()) + + // Enable a failpoint so that the test can create oplogs during dump. + failpoint.ParseFailpoints(failpoint.PauseBeforeDumping) + defer failpoint.Reset() + + go func() { + require.NoError(t, createIndexesAndRunCollModPrepareUnique(ctx)) + }() + + //nolint:errcheck + defer tearDownMongoDumpTestData(t) + + require.NoError(t, md.Dump()) + + path, err := os.Getwd() + require.NoError(t, err) + + dumpDir := util.ToUniversalPath(filepath.Join(path, "collMod_prepareUnique")) + dumpDBDir := util.ToUniversalPath(filepath.Join(dumpDir, testDB)) + oplogFilePath := util.ToUniversalPath(filepath.Join(dumpDir, "oplog.bson")) + require.True(t, fileDirExists(dumpDir)) + require.True(t, fileDirExists(dumpDBDir)) + require.True(t, fileDirExists(oplogFilePath)) + + defer os.RemoveAll(dumpDir) + + oplogFile, err := os.Open(oplogFilePath) + require.NoError(t, err) + defer oplogFile.Close() + + bsonSrc := db.NewDecodedBSONSource(db.NewBufferlessBSONSource(oplogFile)) + prepareUniqueTrueCount := 0 + prepareUniqueFalseCount := 0 + + var oplog db.Oplog + for bsonSrc.Next(&oplog) { + require.NoError(t, bsonSrc.Err()) + + if oplog.Namespace == testDB+".$cmd" { + indexDoc, ok := bsonutil.ToMap(oplog.Object)["index"].(bson.D) + if ok { + if bsonutil.ToMap(indexDoc)["prepareUnique"] == true { + prepareUniqueTrueCount++ + } else { + prepareUniqueFalseCount++ + } + } + } + } + require.NoError(t, oplogFile.Close()) + require.Equal(t, 4, prepareUniqueTrueCount) + require.Equal(t, 4, prepareUniqueFalseCount) +} + +func createIndexesAndRunCollModPrepareUnique(ctx context.Context) error { + client, err := testutil.GetBareSession() + if err != nil { + return err + } + + testCollName := testCollectionNames[0] + + indexes := []mongo.IndexModel{ + { + Keys: bson.D{{"a", 1}}, + }, + { + Keys: bson.D{{"b", 1}}, + Options: options.Index().SetHidden(true), + }, + { + Keys: bson.D{{"c", 1}}, + Options: options.Index().SetExpireAfterSeconds(100000), + }, + { + Keys: bson.D{{"d", 1}}, + Options: options.Index().SetExpireAfterSeconds(100000).SetHidden(true), + }, + } + + _, err = client.Database(testDB).Collection(testCollName).Indexes().CreateMany( + ctx, + indexes, + ) + if err != nil { + return err + } + + for _, index := range indexes { + for _, prepareUnique := range []bool{true, false} { + res := client.Database(testDB).RunCommand( + ctx, + bson.D{ + {"collMod", testCollName}, + {"index", bson.D{ + {"keyPattern", index.Keys}, + {"prepareUnique", prepareUnique}, + }}, + }, + ) + if res.Err() != nil { + return res.Err() + } + } + } + + return nil +} diff --git a/mongorestore/oplog_test.go b/mongorestore/oplog_test.go index 0a3ce2243..65c5a75b1 100644 --- a/mongorestore/oplog_test.go +++ b/mongorestore/oplog_test.go @@ -767,3 +767,51 @@ func testOplogRestoreVectoredInsert(t *testing.T, linked bool) { } require.Equal(t, len(expectedDocs), i) } + +func TestOplogRestoreCollModPrepareUnique(t *testing.T) { + testtype.SkipUnlessTestType(t, testtype.IntegrationTestType) + + ctx := t.Context() + + session, err := testutil.GetBareSession() + if err != nil { + t.Fatalf("Failed to get session: %v", err) + } + //nolint:errcheck + defer session.Disconnect(ctx) + + fcv := testutil.GetFCV(session) + if cmp, err := testutil.CompareFCV(fcv, "6.0"); err != nil || cmp < 0 { + if err != nil { + t.Errorf("error getting FCV: %v", err) + } + t.Skipf("Requires server with FCV 6.0 or later; found %v", fcv) + } + + // Prepare the test by creating the necessary collection. + require.NoError(t, session.Database("mongodump_test_db").Drop(ctx)) + require.NoError(t, session.Database("mongodump_test_db").CreateCollection(ctx, "coll1")) + + oplogFileName := "testdata/oplogs/bson/collMod_prepareUnique.bson" + + args := []string{ + DirectoryOption, "testdata/coll_without_index", + OplogReplayOption, + DropOption, + OplogFileOption, oplogFileName, + } + + restore, err := getRestoreWithArgs(args...) + require.NoError(t, err) + defer restore.Close() + + // Run mongorestore + result := restore.Restore() + require.NoError(t, result.Err) + require.Equal(t, int64(0), result.Failures) + + coll := session.Database("mongodump_test_db").Collection("coll1") + indexSpecs, err := coll.Indexes().ListSpecifications(ctx, options.ListIndexes()) + require.NoError(t, err) + require.Len(t, indexSpecs, 5) +} From 44028133e1e725d5f0e3ca50263e70632cbbd02f Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:52:40 -0500 Subject: [PATCH 2/8] Update oplog_dump_test.go --- mongodump/oplog_dump_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index 92fc7ab96..d1a2c0277 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -8,6 +8,11 @@ package mongodump import ( "context" + "io" + "os" + "path/filepath" + "testing" + "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/failpoint" @@ -20,10 +25,6 @@ import ( "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" - "io" - "os" - "path/filepath" - "testing" ) func TestErrorOnImportCollection(t *testing.T) { From 01981e9ac6588ff87aab2f14e7ee4f0bb93c242c Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Thu, 12 Feb 2026 09:51:11 -0500 Subject: [PATCH 3/8] Update oplog_dump_test.go --- mongodump/oplog_dump_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index d1a2c0277..d9a917b97 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -136,7 +136,9 @@ func vectoredInsert(ctx context.Context) error { func TestOplogDumpCollModPrepareUnique(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.IntegrationTestType) - + // Oplog is not available in a standalone topology. + testtype.SkipUnlessTestType(t, testtype.ReplSetTestType) + ctx := t.Context() session, err := testutil.GetBareSession() From f8e31fc7bde99bac83b8c99db8f464190f49a32b Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Thu, 12 Feb 2026 10:42:46 -0500 Subject: [PATCH 4/8] fix --- mongodump/oplog_dump_test.go | 2 +- .../oplogs/bson/collMod_prepareUnique.bson | Bin 0 -> 3457 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 mongorestore/testdata/oplogs/bson/collMod_prepareUnique.bson diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index d9a917b97..621011266 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -138,7 +138,7 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.IntegrationTestType) // Oplog is not available in a standalone topology. testtype.SkipUnlessTestType(t, testtype.ReplSetTestType) - + ctx := t.Context() session, err := testutil.GetBareSession() diff --git a/mongorestore/testdata/oplogs/bson/collMod_prepareUnique.bson b/mongorestore/testdata/oplogs/bson/collMod_prepareUnique.bson new file mode 100644 index 0000000000000000000000000000000000000000..e5a487384cbf618d2a5c5997f800cdc8dedb7cbb GIT binary patch literal 3457 zcmd58S%5T2ZKaN$o*5YSLW9Cc740c8ZD0Er6)qKjntyu-1Iy=%NSgoc6w35gd# zLWmdO4G=9n0SyHbR4FJyl+5g%!JHy_3(LOZ&gq@GWz*auI1B7)V(&f zKrL8#9L6!cy8LG6HJkWAzeaf6U_(;M_?M|C3^u3eSOQz&(j!}G&~0yKS~;(o1(GnK;s|!XdZn;=zZKzWro-8 z=a}8aNGoCB?Q;qh4lVXnopXMbtiCqI3LRJ-;++3-gprFndYnjg^x(=YbB3fzBe8eg z(xbE=X;H};Puc=7xHJC%qxJd&7+y~L!LNiAfwt~4Fs|6W{nYc4J(ot3;l D)J;4> literal 0 HcmV?d00001 From 8fd9dc1c5f84e5908afeff45dbc496cd38bb1f44 Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Thu, 12 Feb 2026 13:30:07 -0500 Subject: [PATCH 5/8] fix --- common/idx/index_catalog.go | 32 +++--------------- mongodump/oplog_dump_test.go | 4 +-- mongorestore/oplog_test.go | 19 +++++++++-- .../oplogs/bson/collMod_prepareUnique.bson | Bin 3457 -> 4518 bytes 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/common/idx/index_catalog.go b/common/idx/index_catalog.go index b03cbaba9..a1a0a23b9 100644 --- a/common/idx/index_catalog.go +++ b/common/idx/index_catalog.go @@ -337,35 +337,11 @@ func (i *IndexCatalog) collMod(database, collection string, indexModValue any) e return errors.Errorf("cannot find index in indexCatalog for collMod: %v", indexMod) } - expireValue, expireKeyError := bsonutil.FindValueByKey("expireAfterSeconds", &indexMod) - if expireKeyError == nil { - newExpire, ok := expireValue.(int64) - if !ok { - return errors.Errorf( - "expireAfterSeconds must be a number (found %v of type %T): %v", - expireValue, - expireValue, - indexMod, - ) + for k, v := range bsonutil.ToMap(indexMod) { + if k == "keyPattern" || k == "name" { + continue } - err = updateExpireAfterSeconds(matchingIndex, newExpire) - if err != nil { - return err - } - } - - expireValue, hiddenKeyError := bsonutil.FindValueByKey("hidden", &indexMod) - if hiddenKeyError == nil { - newHidden, ok := expireValue.(bool) - if !ok { - return errors.Errorf( - "hidden must be a boolean (found %v of type %T): %v", - expireValue, - expireValue, - indexMod, - ) - } - updateHidden(matchingIndex, newHidden) + matchingIndex.Options[k] = v } // Update the index. diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index 621011266..8a86b6e65 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -218,7 +218,7 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) { } } require.NoError(t, oplogFile.Close()) - require.Equal(t, 4, prepareUniqueTrueCount) + require.Equal(t, 8, prepareUniqueTrueCount) require.Equal(t, 4, prepareUniqueFalseCount) } @@ -257,7 +257,7 @@ func createIndexesAndRunCollModPrepareUnique(ctx context.Context) error { } for _, index := range indexes { - for _, prepareUnique := range []bool{true, false} { + for _, prepareUnique := range []bool{true, false, true} { res := client.Database(testDB).RunCommand( ctx, bson.D{ diff --git a/mongorestore/oplog_test.go b/mongorestore/oplog_test.go index 65c5a75b1..bca3ee4f9 100644 --- a/mongorestore/oplog_test.go +++ b/mongorestore/oplog_test.go @@ -792,7 +792,7 @@ func TestOplogRestoreCollModPrepareUnique(t *testing.T) { require.NoError(t, session.Database("mongodump_test_db").Drop(ctx)) require.NoError(t, session.Database("mongodump_test_db").CreateCollection(ctx, "coll1")) - oplogFileName := "testdata/oplogs/bson/collMod_prepareUnique.bson" + oplogFileName := "testdata/oplogs/bson/oplog.bson" args := []string{ DirectoryOption, "testdata/coll_without_index", @@ -810,8 +810,21 @@ func TestOplogRestoreCollModPrepareUnique(t *testing.T) { require.NoError(t, result.Err) require.Equal(t, int64(0), result.Failures) - coll := session.Database("mongodump_test_db").Collection("coll1") - indexSpecs, err := coll.Indexes().ListSpecifications(ctx, options.ListIndexes()) + db := session.Database("mongodump_test_db") + + cursor, err := db.RunCommandCursor(ctx, bson.D{ + {"listIndexes", "coll1"}, + }) require.NoError(t, err) + + var indexSpecs []bson.M + require.NoError(t, cursor.All(ctx, &indexSpecs)) + require.Len(t, indexSpecs, 5) + + for _, indexSpec := range indexSpecs { + if indexSpec["name"] != "_id_" { + require.True(t, indexSpec["prepareUnique"].(bool)) + } + } } diff --git a/mongorestore/testdata/oplogs/bson/collMod_prepareUnique.bson b/mongorestore/testdata/oplogs/bson/collMod_prepareUnique.bson index e5a487384cbf618d2a5c5997f800cdc8dedb7cbb..a19a6cb57090cc9a5784775059906d851c44da3f 100644 GIT binary patch literal 4518 zcmd6qzi-n(6vtoVgr-p1BvQo)Qkg3iriz6kmJV$t5F3)^_#SY=@frUp?a0E=q3YP7 zLl^!5)=G#8Iw2+okYHfz!p6kFdrmD(6zOiT&W@D$a%bPY@8{n4<#Gl9EfqnFu0FKF z1g=qQq{634WTVJUF-cu9T)F9w1avY9JsNIrtu6ezy>@s0WPkAe&#S?rqhO0C@?-Q; zgiAb`3W8N|q}T`r?!pRn^>*@QoaeX)3;f-c0%oW|>v|)E4z;MurAt3e@{#k_fgGf8 zhi{_SU_1ji=U#e20EffV2gf|cJ9<~5<33L`){#e!Nl8vw!93mA^UCqJsmF6y$I&xT zUGyJ{=s)tJRqVnhPo#;y`%DUfA@EG zzK6S!jB))*it$7ARVWfTc}=Opsl_{`+nle3svlLULIYJ(Hs?Q&aO6TKkBy|0_p^|< zOiU`ty?ePlvi+tKCC@lAF96Ftn%lgvNjHiy@?v}x$`={(9y;n46(PEE@jyS7D%_6v zGjUZQ;06tKvW$wx)FMR1hF2;-u|!WyEJHn<0bHVVi1z)9;?fjE6tfLP7bclCKy=hJ zM0T^NYk=rYt%$ggPdLCXqB#RZZ<~h5uF)MZarB#HZg{jkaijs4eO|I!-}k*Jyk`*JV+^X^89^ Lt#5$ndV%OKRb4-= literal 3457 zcmd58S%5T2ZKaN$o*5YSLW9Cc740c8ZD0Er6)qKjntyu-1Iy=%NSgoc6w35gd# zLWmdO4G=9n0SyHbR4FJyl+5g%!JHy_3(LOZ&gq@GWz*auI1B7)V(&f zKrL8#9L6!cy8LG6HJkWAzeaf6U_(;M_?M|C3^u3eSOQz&(j!}G&~0yKS~;(o1(GnK;s|!XdZn;=zZKzWro-8 z=a}8aNGoCB?Q;qh4lVXnopXMbtiCqI3LRJ-;++3-gprFndYnjg^x(=YbB3fzBe8eg z(xbE=X;H};Puc=7xHJC%qxJd&7+y~L!LNiAfwt~4Fs|6W{nYc4J(ot3;l D)J;4> From 4d874c7c559d45e1a5b9566097c118b1b88f0c25 Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Thu, 12 Feb 2026 14:07:38 -0500 Subject: [PATCH 6/8] lint --- common/idx/index_catalog.go | 12 ------------ mongorestore/oplog_test.go | 6 ++++-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/common/idx/index_catalog.go b/common/idx/index_catalog.go index a1a0a23b9..3160c2d45 100644 --- a/common/idx/index_catalog.go +++ b/common/idx/index_catalog.go @@ -267,18 +267,6 @@ func (i *IndexCatalog) DeleteIndexes(database, collection string, dropCmd bson.D } } -func updateExpireAfterSeconds(index *IndexDocument, expire int64) error { - if _, ok := index.Options["expireAfterSeconds"]; !ok { - return errors.Errorf("missing \"expireAfterSeconds\" in matching index: %v", index) - } - index.Options["expireAfterSeconds"] = expire - return nil -} - -func updateHidden(index *IndexDocument, hidden bool) { - index.Options["hidden"] = hidden -} - // GetIndexByIndexMod returns an index that matches the name or key pattern specified in // a collMod command. func (i *IndexCatalog) GetIndexByIndexMod( diff --git a/mongorestore/oplog_test.go b/mongorestore/oplog_test.go index bca3ee4f9..c8b1d6af1 100644 --- a/mongorestore/oplog_test.go +++ b/mongorestore/oplog_test.go @@ -792,7 +792,7 @@ func TestOplogRestoreCollModPrepareUnique(t *testing.T) { require.NoError(t, session.Database("mongodump_test_db").Drop(ctx)) require.NoError(t, session.Database("mongodump_test_db").CreateCollection(ctx, "coll1")) - oplogFileName := "testdata/oplogs/bson/oplog.bson" + oplogFileName := "testdata/oplogs/bson/collMod_prepareUnique.bson" args := []string{ DirectoryOption, "testdata/coll_without_index", @@ -824,7 +824,9 @@ func TestOplogRestoreCollModPrepareUnique(t *testing.T) { for _, indexSpec := range indexSpecs { if indexSpec["name"] != "_id_" { - require.True(t, indexSpec["prepareUnique"].(bool)) + prepareUnique, ok := indexSpec["prepareUnique"].(bool) + require.True(t, ok) + require.True(t, prepareUnique) } } } From 287cbd3f815b039c48eadf64e200cea0355b8981 Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:44:27 -0500 Subject: [PATCH 7/8] allow list --- common/idx/index_catalog.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/idx/index_catalog.go b/common/idx/index_catalog.go index 3160c2d45..457d8cbb6 100644 --- a/common/idx/index_catalog.go +++ b/common/idx/index_catalog.go @@ -329,7 +329,12 @@ func (i *IndexCatalog) collMod(database, collection string, indexModValue any) e if k == "keyPattern" || k == "name" { continue } - matchingIndex.Options[k] = v + + if k == "expireAfterSeconds" || k == "hidden" || k == "prepareUnique" || k == "unique" { + matchingIndex.Options[k] = v + } else { + return errors.Errorf("unknown index option: %v", k) + } } // Update the index. From 4dcebe88e700936ca4cdc7e94e9bd086b66e97e4 Mon Sep 17 00:00:00 2001 From: Jian Guan <61915096+tdq45gj@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:53:29 -0500 Subject: [PATCH 8/8] Update index_catalog.go --- common/idx/index_catalog.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/idx/index_catalog.go b/common/idx/index_catalog.go index 457d8cbb6..d526f2215 100644 --- a/common/idx/index_catalog.go +++ b/common/idx/index_catalog.go @@ -325,13 +325,15 @@ func (i *IndexCatalog) collMod(database, collection string, indexModValue any) e return errors.Errorf("cannot find index in indexCatalog for collMod: %v", indexMod) } - for k, v := range bsonutil.ToMap(indexMod) { + for _, element := range indexMod { + k := element.Key if k == "keyPattern" || k == "name" { continue } if k == "expireAfterSeconds" || k == "hidden" || k == "prepareUnique" || k == "unique" { - matchingIndex.Options[k] = v + matchingIndex.Options[k] = element.Value + } else { return errors.Errorf("unknown index option: %v", k) }