3

The following code haven't worked for me:

public void addFieldWithValueToDoc(String DBName, String collName, String docID, String key, String value) {
    BasicDBObject setNewFieldQuery = new BasicDBObject().append("$set", new BasicDBObject().append(key, value));
    mongoClient.getDB(DBName).getCollection(collName).update(new BasicDBObject().append("_id", docID), setNewFieldQuery);
}

Where mongoClient variable's type is MongoClient.

It's inspired by Add new field to a collection in MongoDB . What's wrong and how to do it right? Thanks.

Community
  • 1
  • 1
rok
  • 9,403
  • 17
  • 70
  • 126
  • 4
    Your code should work. One thing can be the `_id` field. Is it really `String` or `ObjectId`? If the later is true, change your code to `append("_id", new ObjectId(docID))` – Ori Dar Jan 08 '14 at 08:17
  • 2
    @orid is almost certainly correct - String docID will not match ObjectId() type. – Asya Kamsky Jan 08 '14 at 09:23
  • 1
    In what way hasn't it worked? Was there an error, or did you not get the result you expected? Also, you don't need to do `new BasicDBObject().append(key, value)` you can simply do `new BasicDBObject(key, value)` – Trisha Jan 08 '14 at 13:34

2 Answers2

9

I've written a JUnit test to prove that your code does work:

@Test
public void shouldUpdateAnExistingDocumentWithANewKeyAndValue() {
    // Given
    String docID = "someId";
    collection.save(new BasicDBObject("_id", docID));
    assertThat(collection.find().count(), is(1));

    // When
    String key = "newKeyName";
    String value = "newKeyValue";
    addFieldWithValueToDoc(db.getName(), collection.getName(), docID, key, value);

    // Then
    assertThat(collection.findOne().get(key).toString(), is(value));
}

public void addFieldWithValueToDoc(String DBName, String collName, String docID, String key, String value) {
    BasicDBObject setNewFieldQuery = new BasicDBObject().append("$set", new BasicDBObject().append(key, value));
    mongoClient.getDB(DBName).getCollection(collName).update(new BasicDBObject().append("_id", docID), setNewFieldQuery);
}

So your code is correct, although I'd like to point out some comments on style that would make it more readable:

  1. Parameters and variables should start with a lower-case letter. DBName should be dbName,
  2. You don't need new BasicDBObject().append(key, value) use new BasicDBObject(key, value)

This code does the same thing as your code, but is shorter and simpler:

public void addFieldWithValueToDoc(String dbName, String collName, String docID, String key, String value) {
    mongoClient.getDB(dbName).getCollection(collName).update(new BasicDBObject("_id", docID),
                                                             new BasicDBObject("$set", new BasicDBObject(key, value)));
}
Trisha
  • 3,891
  • 1
  • 25
  • 39
1

To update existing documents in a collection, you can use the collection’s updateOne() or updateMany methods.

updateOne method has the following form:

db.collection.updateOne(filter, update, options)

filter - the selection criteria for the update. The same query selectors as in the find() method are available.

Specify an empty document { } to update the first document returned in the collection.

update - the modifications to apply.

So, if you want to add one more field using Mongodb Java driver 3.4+, it will be:

collection.updateOne(new Document("flag", true),
                        new Document("$set", new Document("title", "Portable Space Ball")));

The following operation updates a single document where flag:true

Or in the same logic:

collection.updateOne(eq("flag", true),
                            new Document("$set", new Document("title", "Portable Space Ball")));

If the title field does not exist, $set will add a new field with the specified value, provided that the new field does not violate a type constraint. If you specify a dotted path for a non-existent field, $set will create the embedded documents as needed to fulfill the dotted path to the field.

invzbl3
  • 5,872
  • 9
  • 36
  • 76