2016-09-15 157 views

回答

3

我通過spring數據搜索mongo文檔和其他資源,但沒有找到預期的答案。

看起來像Mongo一樣插入批處理文檔,直到滿足唯一鍵約束,並由DB決定。

因此,例如,如果您需要插入100個文檔,並且位置50上的文檔已經存在於數據庫中,則前49個將被插入,而後50個不會。

我想出了爲下一個解決方案:

Set<String> ids = foos.stream().map(Foo::getBar).collect(toSet()); // collect all ids from docs that will be inserted 
WriteResult writeResult = mongoTemplate.remove(new Query(Criteria.where("_id").in(ids)), Foo.class); // perform remove with collected ids 
mongoTemplate.insert(foos, Foo.class); // now can safely insert batch 

所以數據庫會被調用兩次。 也作爲bar被索引字段刪除操作將會很快。

1

就我而言,它不適用於修改/覆蓋現有文檔,如@ marknorkin的答案。相反,我只想插入新的文件。我想出了這個使用MongoOperations,這是在春季注射。以下代碼位於Kotlin。

try { 
     // we do not want to overwrite existing documents, especially not behind the event horizon 
     // we hence use unordered inserts and supresss the duplicate key exceptions 
     // as described in: https://docs.mongodb.com/v3.2/reference/method/db.collection.insertMany/#unordered-inserts 
     mongoOps.bulkOps(BulkOperations.BulkMode.UNORDERED, EventContainer::class.java) 
      .insert(filtered) 
      .execute() 
     } catch (ex: BulkOperationException) { 
     if (!isDuplicateKeyException(ex)) { 
      throw ex 
     } 
     } 

有了這個小幫手

private fun isDuplicateKeyException(ex: BulkOperationException): Boolean { 
    val duplicateKeyErrorCode = 11000 
    return ex.errors.all { it.code == duplicateKeyErrorCode } 
}