Skip to content

Commit

Permalink
feat: modify mongo index function (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
scorix authored Nov 13, 2023
1 parent c886960 commit fa87bd0
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package xmongo

import (
"context"
"fmt"

"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

// doc: https://www.mongodb.com/docs/v7.0/tutorial/manage-indexes/#minimize-performance-impact-with-a-temporary-index
func ModifyIndex(ctx context.Context, collection *mongo.Collection, name string, newIndex mongo.IndexModel) error {
// 0. find the existing index
indexes, err := collection.Indexes().ListSpecifications(ctx, options.ListIndexes())
if err != nil {
return fmt.Errorf("list indexes: %w", err)
}

var existingIndex *mongo.IndexSpecification
for _, i := range indexes {
if i.Name == name {
existingIndex = i
}
}

if existingIndex == nil {
return fmt.Errorf("index %s not found", name)
}

rawkeys, err := existingIndex.KeysDocument.Elements()
if err != nil {
return fmt.Errorf("keys document: %w", err)
}

var keys []bson.E
for _, key := range rawkeys {
keys = append(keys, bson.E{Key: key.Key(), Value: 1})
}

const dummyField = "_tmp_dummy_field"
keys = append(keys, bson.E{Key: dummyField, Value: 1})

tmpIndexName := fmt.Sprintf("temp_index_%s", name)

// 1. create a temporary index
if _, err := collection.Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: keys,
Options: &options.IndexOptions{
Name: &tmpIndexName,
},
}); err != nil {
return fmt.Errorf("create temp index: %w", err)
}

// 2. drop the existing index
if _, err := collection.Indexes().DropOne(ctx, name); err != nil {
return fmt.Errorf("drop index %s: %w", name, err)
}

// 3. create the new index
if _, err := collection.Indexes().CreateOne(ctx, newIndex); err != nil {
return fmt.Errorf("create new index: %w", err)
}

// 4. drop the temporary index
if _, err := collection.Indexes().DropOne(ctx, tmpIndexName); err != nil {
return fmt.Errorf("drop temp index: %w", err)
}

return nil
}

0 comments on commit fa87bd0

Please sign in to comment.