2013-12-10 2 views
2

Я пишу актер DAO для MongoDB, который использует ReactiveMongo. Я хочу реализовать некоторые очень простые CRUD-операции, среди которых возможность увеличить количество записей за один снимок. Поскольку у меня есть реактивное приложение (построенное на Akka), для меня важно иметь идемпотентные действия, поэтому мне нужно, чтобы операция была upsert, а не вставкой.Усиление многих записей с помощью ReactiveMongo и Scala

До сих пор я следующее (некрасиво) код, чтобы сделать так:

case class UpsertResult[T](nUpd: Int, nIns: Int, failed: List[T]) 

def upsertMany[T](l: List[T], collection: BSONCollection) 
    (implicit ec: ExecutionContext, w: BSONDocumentWriter[T]): 
    Future[UpsertResult[T]] = { 
     Future.sequence(l.map(o => collection.save(o).map(r => (o, r)))) 
     .transform({ 
      results =>  
      val failed: List[T] = results.filter(!_._2.ok).unzip._1 
      val nUpd = results.count(_._2.updatedExisting) 
      UpsertResult(nUpd, results.size - nUpd - failed.size, failed) 
     }, t => t) 
     }  

Есть ли вне коробки способ upserting много записей одновременно используя reactivemongo API в одиночку?

Я новичок MongoDB, так что это может показаться тривиальным для многих. Любая помощь приветствуется!

ответ

3

У Mongo нет поддержки для увеличения количества документов в одном запросе. Например, операция обновления всегда может вставлять только один новый элемент. Таким образом, это не является недостатком в драйвере reactivemongo, просто нет команды DB для достижения ожидаемого результата. Итерация над документами, которые вы хотите оптимизировать, - это правильный способ сделать это.

Руководство по MongoDB о upsert содержит дополнительную информацию:

http://docs.mongodb.org/manual/core/update/#update-operations-with-the-upsert-flag

+0

Сделав некоторое исследование, я сам пришел к такому выводу. Я также прочитал, что пакетные обновления будут поддерживаться в Mongo 2.6. –

+0

Спасибо за головы, еще не знаю о новой функции. – tmbo

0

Согласно документам, BSSONCollection.save inserts the document, or updates it if it already exists in the collection: see here. Теперь я точно не знаю, как принимает решение о том, существует ли документ или нет: предположительно он основан на том, что говорит MongoDB ... поэтому первичный ключ/идентификатор или уникальный индекс.

Вкратце: я думаю, что вы делаете это правильно (включая результат от LastError).

+0

Я думаю, вы поняли вопрос: мне интересно, если я могу upsert _many_ записи сразу с помощью API. Пойду, чтобы уточнить мой вопрос. –