Как мне обновить поля документов в mongo db с помощью драйвера java? - PullRequest
18 голосов
/ 27 августа 2010

Ссылки:

Все еще довольно плохо знаком с mongo db, но я пытаюсь обновить часть существующего документа внутри коллекции ...К сожалению, приведенная выше ссылка не имеет примера обновления.

По сути, я просто хочу иметь возможность:

  1. Добавить новые поля в документ
  2. Обновите существующие поля документа до нового значения

Вот мой код (Grails + Groovy + Java + MongoDB + драйвер Java):

def shape = mongo.shapes.findOne(new BasicDBObject("data", "http://www.foo.com")); // get the document
mongo.shapes.update(new BasicDBObject("_id", shape._id), new BasicDBObject("isProcessed", 0));  // add a new "isProcessed" field set to 0
mongo.shapes.update(new BasicDBObject("_id", shape._id), new BasicDBObject("data", "http://www.bar.com"));

Это в значительной степени забиваетвесь объект ... Я мог бы попытаться просто изменить исходный объект формы и затем запустить обновление для этого.Но до тех пор, кто-нибудь имеет опыт обновления только отдельных полей (а не всего документа)?

РЕДАКТИРОВАТЬ:

Я только что попробовал и смог успешно обновитьотправив весь объект с новыми и / или обновленными полями, и это работает.Интересно, достаточно ли умен этот драйвер, чтобы обновлять только малейшее подмножество изменений или он просто вслепую обновляет все?(В приведенном ниже случае это просто обновление поля foo на проводе или на всем документе формы?)

Код:

def shape = mongo.shapes.findOne(); // get the first shape to use as a base
shape.removeField("_id");  // remove the id field
shape.put("foo","bar");  // add a new field "foo"
mongo.shapes.insert(shape);  // insert the new shape
def shape2 = mongo.shapes.findOne(new BasicDBObject("foo", "bar"));  // get the newly inserted shape (and more importantly, it's id)
shape2.put("foo", "bat");  // update the "foo" field to a new value
mongo.shapes.update(new BasicDBObject("_id", shape2._id), shape2);  // update the existing document in mongo

Ответы [ 6 ]

12 голосов
/ 27 августа 2010

Интересно, достаточно ли умен драйвер, чтобы обновлять только малейшее подмножество изменений или он просто вслепую обновляет весь объект?

Нет, если вы используете "обычный"Метод обновления, весь объект будет отправлен по проводам.Я подозреваю, что сам сервер базы данных будет достаточно умен, чтобы обновлять только необходимые индексы (а не те, которые не изменились), если это возможно (т. Е. Объект можно было обновить на месте, и его не нужно было перемещать, потому что он тоже вырос)много)

То, что вы можете сделать, это использовать функции «модификатор атомарного обновления».Документация по Java немного разбирается в них, но поскольку драйвер просто передает JSON, материал из не-Java учебников должен работать, например:

shapes.update((DBObject)JSON.parse(    "{ 'foo' : 'bar'}"),  
    (DBObject) JSON.parse(          "{ '$set' : { 'foo': 'bat'}}")   );
11 голосов
/ 27 августа 2010

Найден пример здесь , который, кажется, показывает использование для вызова обновления. Так что для вашего примера, я считаю, что-то вроде этого должно работать?

// Find an object
def shape2 = mongo.shapes.findOne( new BasicDBObject( 'foo', 'bar' ) )
// And update the foo field from 'bar' to 'bat'
mongo.shapes.update( shape2, new BasicDBObject( '$set', new BasicDBObject( 'foo', 'bat' ) ) )

Редактировать

Возможно, вы сможете использовать категорию для создания ваших BasicDBObjects более интересным способом ...

Нечто подобное может сделать это:

class BasicDBObjectMapBuilder {
  static String toDbObj( String s ) { s }
  static BasicDBObject toDbObj( Map m ) {
    m.inject( null ) { r, it -> new BasicDBObject( it.key, it.value.toDbObj() ) }
  }
}

use( BasicDBObjectMapBuilder ) {
  def shape2 = mongo.shapes.findOne( new BasicDBObject( 'foo', 'bar' ) )
  // And update the foo field from 'bar' to 'bat'
  mongo.shapes.update( shape2, [ '$set':[ 'foo', 'bat' ] ].toDbObj() )
}

Хотя я не проверял это ...

Редактировать 2

На самом деле BasicDBObject - это карта, поэтому вы должны иметь возможность:

  mongo.shapes.update( shape2, [ '$set':[ 'foo', 'bat' ] ] as BasicDBObject )

без нужды застройщика

5 голосов
/ 18 января 2016

Многие ответы на этот пост используют более старые версии драйвера Mongo Java.Если вы используете более новую версию драйвера Java (v3.0 +), то предпочтительным методом, вероятно, будет использование объекта Document вместо интерфейса DBObject.

Вот пример:

MongoClient client = new MongoClient();
MongoCollection<Document> fooCollection = client.getDatabase("test").getCollection("foo");

Bson filter = Filters.eq("_id", "123d45678c467bb433c99f99");
Bson updates = Updates.set("isFoo", true);
fooCollection.findOneAndUpdate(filter, updates);
3 голосов
/ 22 января 2013

В этом ответе используется оболочка mongo, но показано, как можно углубиться в структуру объекта JSON, чтобы изменить определенное поле без перезаписи остальных.

Учитывая объект JSON в коллекции под названием «my_collection»:

{ 
  "_id" : ObjectId("50fdb2a73f7bc7a5acecc4f8"), 
  "data" : { 
    "list" : [ 0, 1, 2, 7, 4, 5 ], 
    "subobj" : { 
       "var_a":"valuea",
       "var_b":"valueb" 
     }
  }
}

Чтобы обновить 'var_b', не перезаписывая ничего другого:

db.my_collection.update({"_id":"50fdb2a73f7bc7a5acecc4f8"}, { "$set":{"data.subobj.var_b":"new_value"}})

Чтобы обновить 3-й элемент в массиве 'list' со значением '99', не перезаписывая что-либо еще:

db.my_collection.update({"_id":"50fdb2a73f7bc7a5acecc4f8"}, { "$set":{"data.list.2":"99"} } )
1 голос
/ 24 августа 2012
DBCollection dbCollection = db.getCollection("mycollection");
BasicDBObject dbObject = new BasicDBObject();
dbObject.put("_id", "3"); 
// your update condition - or the query
DBObject newObject =  dbCollection.find(dbObject).toArray().get(0);
// I just take the first element. Can iterate through as per your requirement if multiple fields        exist
newObject.put("key","value");
//add field, either a new field or any existing field
dbCollection.findAndModify(dbObject, newObject);

Просто используйте вышеуказанные шаги.Вы можете изменить детали, не затрагивая другие элементы, связанные с тем же ключом.

0 голосов
/ 25 марта 2013

// обновление

WriteResult usr = (WriteResult)mongoOperation.upsert(new  Query(Criteria.where("name").is("till")),  

Update.update("password", "jk45"), "collection");

System.out.println("updatedUser : " + usr );
...