Это довольно просто сделать. За исключением операций upsert, ObjectId генерируется на стороне клиента. Другими словами, когда вы выполняете операцию сохранения из вашего приложения, драйвер автоматически выполняет (псевдо):
if(!doc.containsKey("_id"))
doc.put(_id, new ObjectId());
Итак, все, что вам нужно сделать, - это сгенерировать ObjectId самостоятельно, делать с ним все, что вам нужно, а затем установить _id вашего документа на это значение, а не делать так, чтобы драйвер монго делал это за вас.
Обратите внимание, что это точно так же безопасно, как если бы драйвер сгенерировал идентификаторы. ObjectIds предназначены для устранения столкновений идентификаторов (читай: маловероятно, что столкновения станут бесполезными). Кроме того, время между генерацией идентификатора и его сохранением также не вызывает проблем с конфликтом идентификаторов.
Если вы сохраните документ с _id, который уже существует в базе данных, он перезапишет исходный документ с этим _id.
Если вы вставите документ с уже существующим _id, вы получите дубликат ошибки _id (ошибка 11000).