2013-04-03 48 views
0

我想添加一個元素到BasicDBList數組並將其保存回Mongodb,但是當我檢查結果時,它沒有寫入。我做錯了什麼?我使用java驅動程序版本2.7.2。Mongodb:無法保存添加到BasicDBList中的新元素

DBObject dbObject = coll.findOne(dbQuery); 

BasicDBList unreadMsgs = (BasicDBList) dbObject.get("unreadMsgs"); 

Logger.debug("before incrementing unreadMsgs" + dbObject.toString()); 

unreadMsgs.add(new BasicDBObject("id", 1).append("unreadMsg", 1)); 
Logger.debug("after incrementing unreadMsgs : " + dbObject.toString()); 
coll.save(dbObject); 
Logger.debug("check result: " + coll.findOne(dbQuery).toString()); 

遞增unreadMsgs之前{ 「_id」:{ 「$ OID」: 「515c5eb88e3278e9c9d55867」}, 「unreadMsgs」:[]}

遞增unreadMsgs後:{ 「_id」:{「$ OID 「: 」515c5eb88e3278e9c9d55867「}, 」unreadMsgs「:[{ 」ID「:1, 」unreadMsg「:1}]}

檢查結果:{ 」_id「:{ 」$ OID「: 」515c5eb88e3278e9c9d55867「}, 「unreadMsgs」:[]}

+0

根據您的配置,您可能在寫入實際發生之前正在讀取。你幾秒鐘後直接從mongo shell檢查過嗎? – assylias 2013-04-04 00:22:27

+0

是的,我直接從mongo shell中檢查了一段時間。結果相同。 – coolsuntraveler 2013-04-04 00:28:40

+0

如果使用ACKNOWLEDGED writeconcern(默認使用MongoClient或者使用Mongo:'mongo.setWriteConcern(WriteConcern.ACKNOWLEDGED);'),則可以檢查是否有錯誤:'WriteResult result = coll.save(dbObject); '看看'result.getError()'是否返回錯誤。 – assylias 2013-04-04 00:37:13

回答

1

問題是,coll.save(dbObject)沒有更新任何東西。

它作爲一個插入,並且由於_id已經存在於集合中,所以你得到了一個duplicateKey異常(因爲配置你只是沒有看到它)。

你必須使用一個更新,here是如何

+0

如果您希望自己的應用捕獲mongo例外,請嘗試將您的mongoClient的writeconcern設置爲1.可能的值包括:** - 1 NONE **即使對於網絡問題,也不會產生異常 - ** 0 NORMAL **例外情況是針對網絡問題提出,但不包括服務器錯誤 ** 1 SAFE **針對網絡問題和服務器錯誤引發異常;在服務器上等待寫入操作 ** 2 REPLICAS_SAFE **針對網絡問題和服務器錯誤引發異常;等待至少2臺服務器進行寫入操作 – AntonioOtero 2013-04-03 23:40:19

+0

根據javadoc的說法,DBCollection.save:「將一個對象保存到此集合(插入或更新基於對象_id)」。既然這個對象已經存在,不應該保存實際做更新操作嗎? [這個問題](http://stackoverflow.com/questions/11717660/mongodb-java-api-difference-between-com-mongodb-dbcollection-save-and-common)說了類似的東西。 – coolsuntraveler 2013-04-03 23:52:21

+0

我運行了你的代碼,它對我來說工作原樣。我仍然建議你明確使用更新。(新的BasicDBObject(「_ id」,dbObject.get(「_ id」)),dbObject);' – AntonioOtero 2013-04-04 15:18:34

1

保存呼籲應該在這種情況下工作,但我建議你使用更新$ addToSet操作。

下面的代碼:

DBObject addToSetObj = BasicDBObjectBuilder.start() 
    .push("$addToSet") 
     .push("unreadMsgs") 
      .add("id", 1) 
      .add("unreadMsg", 1) 
     .pop() 
    .pop() 
.get(); 

// addToSetObj will be { "$addToSet" : { "unreadMsgs" : { "id" : 1 , "unreadMsg" : 1}}} 


coll.update(dbQuery, addToSetObj); 
Logger.debug("check result: " + coll.findOne(dbQuery).toString()); 

如何使用addToSet任何疑問,檢查了這一點:http://docs.mongodb.org/manual/reference/operator/addToSet/

1

感謝大家的回答。我發現了真正的問題。事實證明,我的收藏是封頂的,我不允許在封面收藏中的現有文檔中插入更多數據。在將WriteConcern更改爲FSYNC_SAFE後,我看到了異常。我將所有集合都改爲不封頂,代碼現在可以工作。

相關問題