2016-03-21 24 views
0

我是一個使用MongoDB的新手。我只是通過Maven的進口最新的MongoDB的Java客戶端:MongoDB java客戶端的WriteConcern不起作用

<dependency> 
     <groupId>org.mongodb</groupId> 
     <artifactId>mongo-java-driver</artifactId> 
     <version>3.2.2</version> 
    </dependency> 

然後我寫了一個非常簡單的程序測試插入操作。

 //I use a replicaset 
    MongoClient mongoClient = new MongoClient(
      Arrays.asList(new ServerAddress("10.12.16.136", 29017), 
        new ServerAddress("10.12.16.136", 29018), 
        new ServerAddress("10.12.16.136", 29019))); 

    //I just want to write and ignore any database errors. (This does not work) 
    mongoClient.setWriteConcern(WriteConcern.UNACKNOWLEDGED); 

    //Get database and collection 
    MongoDatabase database = mongoClient.getDatabase("test"); 
    MongoCollection<Document> collection = database.getCollection("realtime"); 

    //This does not work too. 
    collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED); 

    //Make a simple object to insert. I already have a document with the same _id in the database and I don't want to see the exception via the WriteConcern operation. 
    Document doc = Document("longitude", longitude) 
      .append("latitude", latitude) 
      .append("velocity", velocity) 
      .append("soc", soc) 
      .append("_id", 12345678); 

    //WriteConcern.UNACKNOWLEDGED doesn't work. An exception will be raised. 
    collection.insertOne(doc); 

我該如何做正確的事情?

回答

2

這是因爲collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED);產生與從不使用不同的寫入關注新MongoCollection對象:

/** * 創建具有不同的寫入關注新MongoCollection實例。 * * @參數writeConcern新的{@link com.mongodb.WriteConcern}爲集合 返回:一個新的MongoCollection實例與不同writeConcern */

MongoCollection withWriteConcern(WriteConcern writeConcern);

下面的代碼:

MongoCollection<Document> dup = collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED); 
... 
dup.insertOne(doc); 

應該工作,即無募集錯誤。

至於它不會傳播到數據庫中的MongoClient級別寫的擔憂:

public MongoDatabase getDatabase(final String databaseName) { 
    MongoClientOptions clientOptions = getMongoClientOptions(); 
    return new MongoDatabaseImpl(databaseName, clientOptions.getCodecRegistry(), clientOptions.getReadPreference(), 
      clientOptions.getWriteConcern(), createOperationExecutor()); 
} 

正如你所看到的,寫值得關注的是MongoClientOptions忽略傳遞給mongoClient.setWriteConcern()方法的參數值取,這可能是一個錯誤。

因此,要正確設置一個全局寫的關注,你必須創建MongoClientOptions一個實例:

MongoClientOptions options = MongoClientOptions 
    .builder() 
    .writeConcern(WriteConcern.UNACKNOWLEDGED) 
    .build(); 

,並把它傳遞給MongoClient構造。

+1

你沒有正確閱讀所有的代碼。在所有'mongoClient.setWriteConcern(WriteConcern.UNACKNOWLEDGED)'之前也有這條線路。所以他們期待着「全球效應」。關於收集的設置只是一個後果問題。 –

+0

@BlakesSeven編輯的回覆 –

+0

把'.withWriteConcern(WriteConcern.UNACKNOWLEDGED)'添加到'.getDatabase()'或'.getCollection()'的末尾可能會更簡單直接。應該使用。一般來說'UNACKNOWLEDGED'非常「強力」,只有當你真的知道你在做什麼時才應該使用它。當然不是「只是」跳過重複的錯誤,因爲有更好的,「更安全」的方法,以及更少的侵入性方法。請記住OP顯然不是這裏的專家。 –

0

我有這個異常,當在MongoDB中已經存在空集合時,我試圖錯誤地創建一個更多的集合,所以當我刪除現有的集合,然後做了一個後期API,然後它工作對我來說很好.. 所以最好首先刪除你現有的集合,然後嘗試調用任何CRUD API .. 如果有一個帶有Collection的Java實體(name =「STUDENT」),並且您又試圖創建一個集合名稱的學生,這個錯誤來了

+1

這看起來更像是一條評論。 – Sunil