Don't know if this is still actual. Here is the code:
package main
import (
"gopkg.in/mgo.v2"
"log"
"io/ioutil"
"encoding/json"
"gopkg.in/mgo.v2/bson"
)
type Auctions struct {
Auc int `json:"auc" bson:"_id"`
Owner string `json:"owner" bson:"owner"`
}
type AuctionResponse struct {
Auctions []Auctions `json:"auctions"`
}
func main() {
session, err := mgo.Dial("mongodb://127.0.0.1:27017/aucs")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
db := session.DB("aucs")
var AuctionData AuctionResponse
AuctionBody, _ := ioutil.ReadFile("auctions.json")
err = json.Unmarshal(AuctionBody, &AuctionData)
log.Println("performing bulk upsert for %s", "realm")
bulk := db.C("realm").Bulk()
for _, auc := range AuctionData.Auctions {
bulk.Upsert(bson.M{"_id": auc.Auc}, auc)
}
_, err = bulk.Run()
if err != nil {
log.Panic("error performing upsert! error: ", err)
}
}
There are some changes that I've made to check if I was right on real data but I hope it's not hard to understand what's going on. Now let me explain a bit Mongo's part.
- You don't need to get
existing
documents. That would be strange to request all existing documents before updating or inserting them especially on huge databases. -
mgo
'supsert
function requires two parameters:-
selector
document (I prefer to think about it as aboutWHERE
condition in terms of SQL) -
document
that you actually have and that will be inserted into DB if selector query fails
-
- In case of bulk
upsert
there is unlimited amount ofselector - document
pairs available to push in one request likebulk.Upsert(sel1, doc1, sel2, doc2, sel3, doc3)
but in your case there is no point to use this feature. -
upsert
affect only single document so even if youselector
fits multiple documents only first will be updated. In other words,upsert
is more similar to MySQL'sINSERT ... ON DUPLICATE KEY UPDATE
than toUPDATE ... WHERE
. In your case (with unique auction's IDs) singleupsert
looks like MySQL query:INSERT INTO realm (auc, owner) VALUES ('1', 'Hogger') ON DUPLICATE KEY UPDATE owner = 'Hogger';
With
bulk
we can just make multiple upserts in the loop and then run them at once.