2013-07-03 51 views
5
//get the collection 
DBCollection coll = MongoDBClient.getInstance().getAlarmInfoCollection(); 

DBObject query = new BasicDBObject(); 
query.put(aa, "51d2b09f81b8a943f9e825aa"); 

DBObject update = new BasicDBObject(); 
DBObject history = new BasicDBObject(); 
history.put("ishistory", 1); 
history.put("acknowledged", 1); 
history.put("state", 1);   
update.put("$set", history); 
coll.updateMulti(query, update); 

,但有時也可以sucess,有時只更新兩個字段(字段「狀態」沒有更新),並且propram沒有報告任何錯誤。我的程序有錯嗎?MongoDB的,用java同時更新的文件有三個字段,有時只有兩個字段使用程序之前更新MongoDB中的文檔更新

+0

上面「aa」的值是什麼? – Trisha

+0

請檢查'coll.update(查詢,更新)'不'updateMulti()'。 – tostao

+0

但是,如果查詢匹配多個記錄,我認爲需要此更新來更新所有匹配的值? – Trisha

回答

8

我寫了一個單元測試來展示代碼的行爲。這個單元測試證明:

  1. 你應該能夠同時更新多個字段(即 多個字段可以用$設定關鍵字進行更新)
  2. updateMulti將更新所有匹配文檔

(注意,像所有的Java MongoDB的測試此使用TestNG的不JUnit的,但它是在這種情況下非常相似)

@Test 
public void shouldUpdateAllMatchingFieldsUsingMultiUpdate() throws UnknownHostException { 
    MongoClient mongoClient = new MongoClient(); 
    DB db = mongoClient.getDB("myDatabase"); 
    DBCollection coll = db.getCollection("coll"); 
    coll.drop(); 

    //Put some test data in the database 
    for (int i = 0; i < 5; i++) { 
     DBObject value = new BasicDBObject(); 
     value.put("fieldToQuery", "a"); 
     value.put("ishistory", 2+i); 
     value.put("acknowledged", 3+i); 
     value.put("state", 14+i); 
     value.put("someOtherArbitraryField", Math.random() * 1000); 
     System.out.println(value); 
     coll.insert(value); 
    } 

    DBObject query = new BasicDBObject("fieldToQuery", "a"); 

    DBObject history = new BasicDBObject().append("ishistory", 1) 
              .append("acknowledged", 1) 
              .append("state", 1); 

    DBObject update = new BasicDBObject("$set", history); 

    //This syntax for update means that all three fields will be set to the new given value 
    Assert.assertEquals(update.toString(), "{ \"$set\" : { \"ishistory\" : 1 , \"acknowledged\" : 1 , \"state\" : 1}}"); 

    //Do the update, updating every document that matches the query 
    coll.updateMulti(query, update); 

    //find The new values 
    DBCursor updatedDocuments = coll.find(query); 
    for (DBObject updatedDocument : updatedDocuments) { 
     Assert.assertEquals(updatedDocument.get("ishistory"), 1); 
     Assert.assertEquals(updatedDocument.get("acknowledged"), 1); 
     Assert.assertEquals(updatedDocument.get("state"), 1); 
     System.out.println(updatedDocument); 
    } 
} 

這個測試經過。舉個例子來說,在數據庫中的數據是:

{ "fieldToQuery" : "a" , "ishistory" : 2 , "acknowledged" : 3 , "state" : 14 , "someOtherArbitraryField" : 700.7831275035031} 
{ "fieldToQuery" : "a" , "ishistory" : 3 , "acknowledged" : 4 , "state" : 15 , "someOtherArbitraryField" : 72.65538582882736} 
{ "fieldToQuery" : "a" , "ishistory" : 4 , "acknowledged" : 5 , "state" : 16 , "someOtherArbitraryField" : 980.0065367659304} 
{ "fieldToQuery" : "a" , "ishistory" : 5 , "acknowledged" : 6 , "state" : 17 , "someOtherArbitraryField" : 91.58266286854722} 
{ "fieldToQuery" : "a" , "ishistory" : 6 , "acknowledged" : 7 , "state" : 18 , "someOtherArbitraryField" : 448.19176202797115} 

在測試結束後,updateMulti時調用$集合運算符後,在數據庫中的文件是:

{ "fieldToQuery" : "a" , "ishistory" : 1 , "acknowledged" : 1 , "state" : 1 , "someOtherArbitraryField" : 700.7831275035031} 
{ "fieldToQuery" : "a" , "ishistory" : 1 , "acknowledged" : 1 , "state" : 1 , "someOtherArbitraryField" : 72.65538582882736} 
{ "fieldToQuery" : "a" , "ishistory" : 1 , "acknowledged" : 1 , "state" : 1 , "someOtherArbitraryField" : 980.0065367659304} 
{ "fieldToQuery" : "a" , "ishistory" : 1 , "acknowledged" : 1 , "state" : 1 , "someOtherArbitraryField" : 91.58266286854722} 
{ "fieldToQuery" : "a" , "ishistory" : 1 , "acknowledged" : 1 , "state" : 1 , "someOtherArbitraryField" : 448.19176202797115} 

因此更新已經起作用,將所有匹配文檔的三個字段設置爲1,而不觸及文檔上的任何其他數據。

這可能是值得指出的是,我對設置的查詢,更新和歷史語法是有點更具可讀性和有點短,但它應該做同樣的事情,在原來問題的代碼:

DBObject query = new BasicDBObject("fieldToQuery", "a"); 

DBObject history = new BasicDBObject().append("ishistory", 1) 
             .append("acknowledged", 1) 
             .append("state", 1); 

DBObject update = new BasicDBObject("$set", history); 

我是否正確地假設您希望與您的query匹配的所有記錄都使用給定值進行更新?因此你使用updateMulti?

+0

這是不正確的答案,它只會設置最後一個值。 – tostao

+0

什麼只會設置最後一個值? updateMulti?還是$集? – Trisha

+0

你的回答只更新'狀態'。 – tostao

相關問題