web-dev-qa-db-fra.com

Comment mettre à jour des champs de documents dans mongo db à l'aide du pilote Java?

Références:

Encore assez nouveau sur mongo db mais j'essaye de mettre à jour une partie d'un document existant à l'intérieur d'une collection ... malheureusement, le lien ci-dessus n'a pas d'exemple de mise à jour.

Essentiellement, je veux juste pouvoir:

  1. Ajouter de nouveaux champs à un document
  2. Mettre à jour les champs existants d'un document avec une nouvelle valeur

Voici mon code (Grails + Groovy + Java + MongoDB + le pilote 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"));

C’est à peu près tout ce qui recouvre l’objet entier ... Je pourrais essayer de modifier simplement l’objet de forme original et d’exécuter ensuite la mise à jour. Mais jusque-là, quelqu'un a-t-il de l'expérience dans la mise à jour de champs individuels (plutôt que du document entier)?

MODIFIER:

Je viens de l'essayer et j'ai réussi à mettre à jour en envoyant l'objet entier avec des champs nouveaux et/ou mis à jour et cela fonctionne. Je me demande si le pilote est suffisamment intelligent pour ne mettre à jour que le plus petit sous-ensemble de modifications ou s'il s'agit simplement de mettre à jour aveuglément le tout? (Dans le cas ci-dessous, s'agit-il simplement de mettre à jour le champ foo via le fil ou le document de forme entier?)

Code:

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
18
longda

Je me demande si le pilote est suffisamment intelligent pour ne mettre à jour que le plus petit sous-ensemble de modifications ou s'il s'agit simplement de mettre à jour aveuglément le tout?

Non, si vous utilisez la méthode de mise à jour "normale", tout l'objet sera envoyé par le fil. Je suppose que le serveur de base de données lui-même sera suffisamment intelligent pour mettre à jour uniquement les index nécessaires (et non ceux n'a pas changé), si possible (l'objet a pu être mis à jour sur place et n'a pas dû être déplacé car il a trop grandi)

Ce que vous pouvez faire est d'utiliser les fonctions "Modificateur de mise à jour atomique". La documentation Java est un peu légère sur eux, mais comme le pilote ne transmet que le JSON, le contenu des tutoriels non-Java devrait fonctionner, par exemple:

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

Trouvé un exemple ici , qui semble indiquer l'utilisation de l'appel de mise à jour. Donc, pour votre exemple, je crois que quelque chose comme ça devrait marcher?

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

Modifier

Vous pourrez peut-être utiliser une catégorie pour construire vos BasicDBObjects d'une manière plus groovy ...

Quelque chose comme ça pourrait le faire:

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() )
}

Je n'ai pas testé cela cependant ...

Modifier 2

En réalité, BasicDBObject est une carte, vous devriez donc pouvoir faire:

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

sans avoir besoin du constructeur

11
tim_yates

Une grande partie des réponses à ce message utilisent d'anciennes versions du pilote Java Mongo. Si vous utilisez une version plus récente du pilote Java (v3.0 +), la méthode préférée semble être d'utiliser l'objet Document à la place de l'interface DBObject.

Voici un exemple:

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

Cette réponse utilise le shell mongo, mais montre comment vous pouvez approfondir une structure d'objet JSON pour modifier un champ spécifique sans écraser le reste.

Étant donné l'objet JSON dans une collection appelée 'my_collection':

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

Pour mettre à jour 'var_b', sans écraser quoi que ce soit d'autre:

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

Pour mettre à jour le 3ème élément du tableau 'list' avec la valeur '99', sans rien remplacer:

db.my_collection.update({"_id":"50fdb2a73f7bc7a5acecc4f8"}, { "$set":{"data.list.2":"99"} } )
3
ElStepherino
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);

Utilisez simplement les étapes ci-dessus. Vous pouvez modifier les détails sans affecter les autres éléments associés à la même clé. 

1
Arun A K

// mettre à jour 

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

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

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