7
//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);

前にプログラムを使用してmongodbのドキュメントを更新しましたが、成功することもあれば、2つのフィールドのみを更新することもあり(フィールド「状態」は更新されません)、プロプラムはエラーを報告しませんでした。私のプログラムに間違いはありますか?

4

1 に答える 1

9

コードがどのように動作するかを示す単体テストを作成しました。この単体テストは、次のことを証明します。

  1. 一度に複数のフィールドを更新できる必要があります (つまり、複数のフィールドは $set キーワードで更新できます)。
  2. updateMulti は一致するすべてのドキュメントを更新します

(注: すべての Java MongoDB テストと同様に、これは JUnit ではなく TestNG を使用しますが、この場合はかなり似ています)

@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 が $set 演算子で呼び出された後、データベース内のドキュメントは次のようになります。

{ "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}

したがって、更新は機能し、一致するすべてのドキュメントの 3 つのフィールドを 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 を使用しますか?

于 2013-07-03T11:27:20.563 に答える