Skip to content

Commit

Permalink
Add bulk upsert method.
Browse files Browse the repository at this point in the history
  • Loading branch information
niemeyer committed Sep 8, 2015
1 parent 93b17aa commit 5df5953
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
24 changes: 24 additions & 0 deletions bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,30 @@ func (b *Bulk) UpdateAll(pairs ...interface{}) {
}
}

// Upsert queues up the provided pairs of upserting instructions.
// The first element of each pair selects which documents must be
// updated, and the second element defines how to update it.
// Each pair matches exactly one document for updating at most.
func (b *Bulk) Upsert(pairs ...interface{}) {
if len(pairs)%2 != 0 {
panic("Bulk.Update requires an even number of parameters")
}
action := b.action(bulkUpdate)
for i := 0; i < len(pairs); i += 2 {
selector := pairs[i]
if selector == nil {
selector = bson.D{}
}
action.docs = append(action.docs, &updateOp{
Collection: b.c.FullName,
Selector: selector,
Update: pairs[i+1],
Flags: 1,
Upsert: true,
})
}
}

// Run runs all the operations queued up.
func (b *Bulk) Run() (*BulkResult, error) {
var result BulkResult
Expand Down
23 changes: 23 additions & 0 deletions bulk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,26 @@ func (s *S) TestBulkMixedUnordered(c *C) {
c.Assert(res, DeepEquals, []doc{{2}, {3}, {4}})
}

func (s *S) TestBulkUpsert(c *C) {
session, err := mgo.Dial("localhost:40001")
c.Assert(err, IsNil)
defer session.Close()

coll := session.DB("mydb").C("mycoll")

err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3})
c.Assert(err, IsNil)

bulk := coll.Bulk()
bulk.Upsert(M{"n": 2}, M{"$set": M{"n": 20}})
bulk.Upsert(M{"n": 4}, M{"$set": M{"n": 40}}, M{"n": 3}, M{"$set": M{"n": 30}})
r, err := bulk.Run()
c.Assert(err, IsNil)
c.Assert(r, FitsTypeOf, &mgo.BulkResult{})

type doc struct{ N int }
var res []doc
err = coll.Find(nil).Sort("n").All(&res)
c.Assert(err, IsNil)
c.Assert(res, DeepEquals, []doc{{1}, {20}, {30}, {40}})
}

0 comments on commit 5df5953

Please sign in to comment.