Search This Blog

Monday, 16 June 2014

UD - The Update and Delete in CRUD

We have already seen Create and Read operations with MongoDB. We were able to create collections in the database and add documents to them. Now to try updating and deletion of documents.
Consider the below method:
   public static void singleSave() throws UnknownHostException {  
      int ID =111;
      BasicDBObject newFruit = new BasicDBObject("name", "pineapple");
      newFruit.append("color", "unknown");
      newFruit.append("rating", 2);
      newFruit.append("_id", ID);
      newFruit.append("weight", 1.03);

      Mongo mongoClient = new Mongo();
      DB targetDB = mongoClient.getDB(DB_NAME);
      DBCollection collection = targetDB.getCollection(COLLECTION_NAME);
      collection.insert(newFruit);
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));
      
      // now to update the Pineapple
      BasicDBObject updateFruit = new BasicDBObject("_id", ID);
      updateFruit.append("color", "yellow");
      collection.save(updateFruit);

      // to display the updated fruit
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));
      mongoClient.close();
   }
In the above code we
  1. created a pineapple object
  2. we then fetched it and displayed it
  3. we now updated the pineapple object to have a color and then saved it.
  4. We did a final fetch to see the updated property.
On running the code:
The details of pineapple are : 
{ "_id" : 111 , "name" : "pineapple" , "color" : "unknown" , "rating" : 2 , "weight" : 1.03}
The details of pineapple are : { "_id" : 111 , "color" : "yellow"}
The result is not exactly what I expected. While the color of pineapple was updated the remaining properties disappeared from the document. Thing is when we use the save method to modify a document, it will remove the old document with the specified id and replace it with the new document. So the only properties that make it to the database are those that are present in the new document.
Instead if we just wanted to update pineapple color the below method would have been more correct.
  public static void singleUpdate() throws UnknownHostException {
      int ID = 108;
      BasicDBObject newFruit = new BasicDBObject("name", "pineapple");
      newFruit.append("color", "unknown");
      newFruit.append("rating", 2);
      newFruit.append("_id", ID);
      newFruit.append("weight", 1.03);

      Mongo mongoClient = new Mongo();
      DB targetDB = mongoClient.getDB(DB_NAME);
      DBCollection collection = targetDB.getCollection(COLLECTION_NAME);
      collection.insert(newFruit);
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));

      // now to update the Pineapple
      BasicDBObject updateFruit = new BasicDBObject("$set", new BasicDBObject().append("color", "yellow"));
      collection.update(new BasicDBObject("_id", ID), updateFruit);

      // to display the updated fruit
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));
      mongoClient.close();
   }
The highlighted line is interesting.If I were to use the update method as below:
BasicDBObject updateFruit = new BasicDBObject("color", "yellow");  
collection.update(new BasicDBObject("_id", ID), updateFruit);
then the code would have worked exactly like our save method. We need to tell the update method that we want the properties in the second BasicDBObject to be added to our existing documents. For this we use the $set operator:(from the docs)
Use the $set operator to replace the value of a field to the specified value. 
If the field does not exist, the $set operator will add the field with the specified value.
The update method has an overloaded version that takes two additional parameters:
  • should multiple documents be updated if they satisfy the query object
  • in case no record is present that matches the query should a new record be inserted
Both parameters are boolean and default to false.
For deletion we have the remove method:
public static void removeSingleDoc() throws UnknownHostException {
      int ID = 108;
      Mongo mongoClient = new Mongo();
      DB targetDB = mongoClient.getDB(DB_NAME);
      DBCollection collection = targetDB.getCollection(COLLECTION_NAME);
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));
      BasicDBObject newFruit = new BasicDBObject("name", "pineapple"); 
      collection.remove(newFruit);
      System.out.println("The details of pineapple are : "
            + collection.findOne(new BasicDBObject("_id", ID)));
      mongoClient.close();
   }
Here we have specified using a query object that the pineapple document needs to be removed. This will in fact remove all documents with name attribute having value 'pineapple'. The output indicates successful deletion of our target record:
The details of pineapple are : { "_id" : 108 , "color" : "yellow" , "name" : "pineapple" , "rating" : 2 , "weight" : 1.03}
The details of pineapple are : null
As the parameter is any query object we can specify any kind of a delete criteria:
collection.remove(new BasicDBObject("_id", 
              new BasicDBObject("$gt", 100).append("$lt", 115)));
This will clear out records in the specified range for _id. If we run the remove method without any parameters (overloaded version) it will delete all the records from the collection. Similar to "Delete from table;"
This would be a very slow operation. MongoDB instead recommends:
To remove all documents from a collection, it may be more efficient to use the drop() method to 
drop the entire collection, including the indexes, and then recreate the collection and rebuild 
the indexes.
Like this code
public static void dropCollection() throws UnknownHostException {
      Mongo mongoClient = new Mongo();
      DB targetDB = mongoClient.getDB(DB_NAME);
      DBCollection collection = targetDB.getCollection("PlayerStore");
      collection.dropIndexes();// will drop all indices for the collection
      collection.drop();// will drop the records and indices in the collection
      mongoClient.close();
   }

No comments:

Post a Comment