1. 程式人生 > >mongodb 3.2.2 版本批量寫入或更新

mongodb 3.2.2 版本批量寫入或更新

   mongodb java driver 從3.0開始,支援同步、非同步寫入更新。這兩個driver使用的包不一樣。比如非同步的需要用async包。如下:

<dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongodb-driver-async</artifactId>
      <version>${mongo.version}</version>
    </dependency>

     MongoDB非同步驅動利用Netty或Java7的AsynchronousSocketChannel 來提供一個支援非同步的API,以支援快速的、非阻塞式的IO操作。該API形式和MongoDB同步驅動的新API保持一致,但是任何會導致網路IO的方法都會有一個SingleResponseCallback並且會立即返回,其中T是響應對於該文件的型別的任何方法。SingleResponseCallback  回撥介面需要實現一個簡單方法onResult(T result, Throwable t) ,這個方法在操作完成時被呼叫。其中,如果操作成功, result引數包含著操作結果;如果操作失敗,t中包含著丟擲的異常資訊。這段參考摘自《

https://cloud.tencent.com/developer/article/1014557

      在使用mongodb非同步批量寫入的時候,必須實現回撥函式,否則無法保證這次批量寫入更新是否成功或者出現異常,如果出問題,就是出現這次批量寫入更新有一部分執行完成了,一部分被中斷沒被執行。因為批量寫入更新都是不保證事務。mongodb這邊能保證的事務,預設是1000條每次。所以能看到的就是mongdb在批量寫入表數量增長的步長是1000,也可以看mongdb server 的log,每次處理是1000條。

批量操作

   批量操作允許批量的執行 插入、更新、刪除操作。批量操作有兩種型別:

  1. 有序的批量操作

       有序的執行所有操作並在第一個寫操作的錯誤處報告錯誤。

  1. 無序的批量操作

       執行所有的操作並報告任何錯誤。無序的批量操作不保證執行順序。

我們來圍觀一下兩個分別使用有序和無序操作的簡單例子:

先定義回撥函式,列印
​​​​​​​SingleResultCallback<BulkWriteResult> printBatchResult = new SingleResultCallback<BulkWriteResult>() {
    @Override
    public void onResult(final BulkWriteResult result, final Throwable t) {
        System.out.println(result);
        //在這個地方可以呼叫result,獲取是否write執行完成,以及此次執行更新的條數
        //或者這次批量更新出現,返回的異常資訊,從t中可以獲取
    }
};

// 2. 有序批量操作
collection.bulkWrite(
  Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                new InsertOneModel<>(new Document("_id", 5)),
                new InsertOneModel<>(new Document("_id", 6)),
                new UpdateOneModel<>(new Document("_id", 1),
                                     new Document("$set", new Document("x", 2))),
                new DeleteOneModel<>(new Document("_id", 2)),
                new ReplaceOneModel<>(new Document("_id", 3),
                                      new Document("_id", 3).append("x", 4))),
  printBatchResult
);


 // 2. 無序批量操作
collection.bulkWrite(
  Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                new InsertOneModel<>(new Document("_id", 5)),
                new InsertOneModel<>(new Document("_id", 6)),
                new UpdateOneModel<>(new Document("_id", 1),
                                     new Document("$set", new Document("x", 2))),
                new DeleteOneModel<>(new Document("_id", 2)),
                new ReplaceOneModel<>(new Document("_id", 3),
                                      new Document("_id", 3).append("x", 4))),
  new BulkWriteOptions().ordered(false),
  printBatchResult
);

重要提示

     不推薦在pre-2.6的MongoDB 伺服器上使用 bulkWrite 方法。因為這是第一個支援批量寫操作(插入、更新、刪除)的伺服器版本,它允許驅動去實現 BulkWriteResultBulkWriteException 的語義。這個方法雖然仍然可以在pre-2.6伺服器上工作,但是效能不好,一次只能執行一個寫操作。