diff --git a/mongo/collection.go b/mongo/collection.go index 9da9240c5e..be7534978e 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -422,18 +422,9 @@ func (coll *Collection) InsertMany( documents any, opts ...options.Lister[options.InsertManyOptions], ) (*InsertManyResult, error) { - - dv := reflect.ValueOf(documents) - if dv.Kind() != reflect.Slice { - return nil, fmt.Errorf("invalid documents: %w", ErrNotSlice) - } - if dv.Len() == 0 { - return nil, fmt.Errorf("invalid documents: %w", ErrEmptySlice) - } - - docSlice := make([]any, 0, dv.Len()) - for i := 0; i < dv.Len(); i++ { - docSlice = append(docSlice, dv.Index(i).Interface()) + docSlice, err := _switch(documents) + if err != nil { + return nil, err } result, err := coll.insert(ctx, docSlice, opts...) @@ -467,6 +458,40 @@ func (coll *Collection) InsertMany( } } +func _switch(documents interface{}) ([]any, error) { + + bytes, err := bson.Marshal(struct { + Arr any `bson:"arr"` + }{Arr: documents}) + if err != nil { + return nil, fmt.Errorf("invalid documents: %w", err) + } + + raw := bson.Raw(bytes).Lookup("arr") + + var docSlice []any + switch raw.Type { + case bson.TypeArray: + elems, err := bson.Raw(raw.Array()).Elements() + if err != nil { + return nil, fmt.Errorf("invalid documents: %w", err) + } + + if len(elems) == 0 { + return nil, fmt.Errorf("invalid documents: %w", ErrEmptySlice) + } + + docSlice = make([]any, len(elems)) + for i, elem := range elems { + docSlice[i] = elem.Value().Document() + } + default: + return nil, fmt.Errorf("invalid documents: %w", ErrNotSlice) + } + + return docSlice, nil +} + func (coll *Collection) delete( ctx context.Context, filter any,