Подтвердить что ты не робот

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

Литература:

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

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

  • Добавить новые поля в документ
  • Обновление существующих полей документа к новому значению

Здесь мой код (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"));

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

EDIT:

Я только что попробовал и смог успешно обновить, отправив весь объект через новые и/или обновленные поля, и это работает. Интересно, достаточно ли водитель достаточно умный, чтобы обновлять только самые маленькие подмножества изменений или просто слепо обновлять всю вещь? (В приведенном ниже примере это просто обновление поля 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 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
4b9b3361

Ответ 1

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

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

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

shapes.update((DBObject)JSON.parse(    "{ 'foo' : 'bar'}"),  
    (DBObject) JSON.parse(          "{ '$set' : { 'foo': 'bat'}}")   );

Ответ 2

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

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

Изменить

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

Что-то вроде этого может это сделать:

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 )

без создания компоновщика

Ответ 3

Многие ответы на этот пост используют более старые версии Mongo Java Driver. Если вы используете более новую версию драйвера 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);

Ответ 4

Этот ответ использует оболочку 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"} } )

Ответ 5

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

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

Ответ 6

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

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

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

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