Important
Much to my dismay, I cannot suggest to use mgo any more, since it seems to be no longer maintained as of the time of this writing.
I was curious and compiled a little benchmark of my own. It uses a single instance MongoDB via docker:
$ docker run -d --name mongobench -p 27017:27017 mongo
731e5f57d677718244c2304a992abd44a5a4bbad6f1fd8e5a23e53b3c4f9ada4
Note: The hash you get will be different.
As per the benchmark, it is twofold: simple insert and bulk inserts. Bulk inserts are the preferred way of dealing with mass insertions.
It tests both the mgo driver and the mongo-go-driver:
package mongobench
// Use
// docker run -d --name mongobench -p 27017:27017 mongo
// to create a suitable test instance and access it via
// docker exec -it mongobench mongo
import (
"context"
"log"
"testing"
"github.com/globalsign/mgo"
"github.com/globalsign/mgo/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Data struct {
ID primitive.ObjectID `bson:"_id"`
Counter int
}
const DefaultHost = "localhost:27017"
const DefaultDB = "test"
const DefaultCollection = "bench"
var sess *mgo.Session
var client *mongo.Client
func init() {
var err error
sess, err = mgo.Dial(DefaultHost)
if err != nil {
log.Fatalf("setting up session: %s", err)
}
client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://" + DefaultHost))
if err != nil {
log.Fatalf("setting up client: %s", err)
}
if err = client.Connect(context.Background()); err != nil {
log.Fatalf("connecting with client: %s", err)
}
}
func BenchmarkMgoInsert(b *testing.B) {
c := sess.DB(DefaultDB).C("simple")
if _, err := c.RemoveAll(bson.M{}); err != nil {
b.Logf("cleaning collection 'simple': %s", err)
b.FailNow()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := c.Insert(&Data{ID: bson.NewObjectId(), Counter: i}); err != nil {
b.Logf("error inserting: %s", err)
b.FailNow()
}
}
}
func BenchmarkMgoBulk(b *testing.B) {
c := sess.DB(DefaultDB).C("bulk")
if _, err := c.RemoveAll(bson.M{}); err != nil {
b.Logf("cleaning collection 'simple': %s", err)
b.FailNow()
}
b.ResetTimer()
bulk := c.Bulk()
for i := 0; i < b.N; i++ {
bulk.Insert(&Data{ID: bson.NewObjectId(), Counter: i})
}
if _, err := bulk.Run(); err != nil {
b.Logf("executing bulk: %s", err)
b.FailNow()
}
}
func BenchmarkMongoInsert(b *testing.B) {
c := client.Database(DefaultDB).Collection("mongosimple")
if _, err := c.DeleteMany(context.Background(), bson.M{}); err != nil {
b.Logf("cleaning collection 'mongosimple': %s", err)
b.FailNow()
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.InsertOne(context.Background(), &Data{ID: bson.NewObjectId(), Counter: i})
}
}
func BenchmarkMongoBulk(b *testing.B) {
c := client.Database(DefaultDB).Collection("mongobulk")
if _, err := c.DeleteMany(context.Background(), bson.M{}); err != nil {
b.Logf("cleaning collection 'mongosimple': %s", err)
b.FailNow()
}
d := make([]mongo.WriteModel, b.N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
d[i] = mongo.NewInsertOneModel().SetDocument(Data{ID: bson.NewObjectId(), Counter: i})
}
if _, err := c.BulkWrite(context.Background(), d); err != nil {
b.Logf("inserting bulk: %s", err)
b.FailNow()
}
}
goos: darwin
goarch: amd64
pkg: github.com/mwmahlberg/so-mongobench
BenchmarkMgoInsert-4 1164 1100919 ns/op 1501 B/op 44 allocs/op
BenchmarkMgoBulk-4 201560 6512 ns/op 258 B/op 4 allocs/op
BenchmarkMongoInsert-4 1171 1019140 ns/op 3642 B/op 66 allocs/op
BenchmarkMongoBulk-4 181040 7251 ns/op 1151 B/op 15 allocs/op
What we can see is that both drivers are orders of magnitude faster than what you describe, hence it is safe to assume that it is not the driver causing the delays.
mgo.Dial()call before starting the timer, to make sure your session is ready.mongodumpetc) are written in Go.id(not_id, mind you). That basically means a collection scan is happening. Gist: MongoDB needs to open each and every document, read it, compare the value of the fieldidwith 1. Btw, your code does not even compile - I have the feeling that you withhold information either accidentally or intentionally. If code is missing, that precludes us from helping you properly.