2

Sometimes I read a piece of code written by experts that raises a big red flag because it clearly is concerned about things that I know nothing about - and probably should.

In this case, here's the implementation of reactivemongo's BSONCollection.save(), which does an upsert based on ObjectId:

def save(doc: BSONDocument, writeConcern: GetLastError)(implicit ec: ExecutionContext): Future[LastError] = {
    doc.get("_id").map { id =>
      update(BSONDocument("_id" -> id), doc, writeConcern, upsert = true)
    }.getOrElse(insert(doc.add("_id" -> BSONObjectID.generate), writeConcern))
  }

Note the get() method is used to first determine whether the document exists, and then either an update-upsert or an insert is done, depending. But AFAIK, the update() method alone (note "upsert=true") would do exactly the same thing. What am I missing?

I'm guessing that the same concerns (whatever they are) also apply to any upsert with a unique-index "find" clause - not just ObjectId. Is that correct?

Ed Staub
  • 15,480
  • 3
  • 61
  • 91

1 Answers1

2
doc.get

only gets the _id field of the document, it doesn't do a query. Reactivemongo just check if you have a _id field, if you do, then it just upsert the document. If you don't have an _id field, then reactivemongo generate one for you. This snippet of code just shows that with mongo, the _id field is generated client side (see https://groups.google.com/forum/#!topic/mongodb-user/pr-KHTMfA3o on why)

  • Ah yes, of course... I should probably delete the question, noone else is likely to misread the same way. – Ed Staub Jan 28 '15 at 01:46