Search This Blog

Thursday, March 1, 2018

Exploring CRUD operation in mongo Part I


we need a collection on which we can run our mongo queries.Lets create a collection for the same.

One can create a mongo collection using 'createCollection' function as follows


    db.createCollection("crudops")


lets add some dummmy data into this collection as follows


    db.crudops.insert({"name":"Samsung Galaxy Note 1","ram":2,"os":"Jelly Bean","company":"samsung india","display":"gorilla glass"})

    db.crudops.insert({"name":"Samsung Galaxy S9 +","ram":6,"os":"Oreo","company":"samsung india","display":"Super AMOLED"})

    db.crudops.insert({"name":"iPhone x","ram":3,"os":"iOS 11.1.1","company":"Apple india","display":"Super AMOLED"})

    db.crudops.insert({"name":"Oppo A17","ram":4,"os":"Nougat","company":"Oppo india","display":"IPS LCD"})

    db.crudops.insert({"name":"Google Pixel 2","ram":4,"os":"Oreo","company":"Google india","display":"AMOLED"})

    db.crudops.insert({"name":"Google Pixel XL","ram":4,"os":"Oreo","company":"Google india","display":"AMOLED"})


we can search all document for samsung india as follows

    db.crudops.find({company: "samsung india"},{}).pretty()

Lets explore some CRUD functionality

1) findAndModify:
 Here findAndModify return value of record before update.'findAndModify' doesn't allow updating multiple documents at a time.

    you can only update one document and it returns the original doc by default.

        Query:

            db.crudops.findAndModify({

                query: { company: "samsung india"},

                sort: { ram: 1 },

                update: { company: "samsung" } ,

                upsert: false

            })


        output:

            { "_id" : ObjectId("5a98118839eb5b1254451ec5"), "company" : "samsung india" }


    Returning updated document:

       Here we are setting 'new' as true so we are getting updated record.default value of 'new' is false.

        Query:

            db.crudops.findAndModify({

                    query: { company: "samsung india"},

                    sort: { ram: 1 },

                    update: { company: "samsung" } ,

                    upsert: false,

                    new: true

                })

        output:

            { "_id" : ObjectId("5a9811d339eb5b1254451ec6"), "company" : "samsung" }

Here in above two 'findAndModify' operations update field is replacing entire document with value specified for 'update' to update particular field we need to use $set

db.crudops.findAndModify({
        query: { company: "Google"},
        sort: { ram: 1 },
        update:  { $set: {"company": "Google INC" } },
        upsert: false,
        new: true
    })

Old Record:
    {
        "_id" : ObjectId("5a9812fa39eb5b1254451eca"),
        "name" : "Google Pixel XL",
        "ram" : 4,
        "os" : "Oreo",
        "company" : "Google",
        "display" : "AMOLED"
    }


New Record:
{
    "_id" : ObjectId("5a9812fa39eb5b1254451eca"),
    "name" : "Google Pixel XL",
    "ram" : 4,
    "os" : "Oreo",
    "company" : "Google INC",
    "display" : "AMOLED"
}

Here only field 'company' is updated rather than replacing entire document except _id.

2) update:

    with 'update' we can update multiple document matching criteria in single query but we need to set  'multi: true', so that multiple documents matching filter get updated otherwise default behaviour is to update only one.


    Query:  

        db.crudops.update(

          {company: "Google india"},

          {

            $set: {

              "company": "Google"

            }

          },

         {

             upsert: false,

             multi: true,

         }

        );


    output:

        WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })


   

        we can cross-verify update result with

        db.crudops.find({company: "Google"},{}).pretty()


3)Findoneandupdate:

    Query:  

        db.crudops.findOneAndUpdate(

                {company: "Google"},

                {$set: {"company": "google"}},

                    {sort : { "name" : 1 } }

            )


    Output:Old record is returned by default

        {

            "_id" : ObjectId("5a9812c839eb5b1254451ec9"),

            "name" : "Google Pixel 2",

            "ram" : 4,

            "os" : "Oreo",

            "company" : "Google",

            "display" : "AMOLED"

        }


    returning new record

        'returnNewDocument : true' is needed for returing updated document.

         Query:  

           db.crudops.findOneAndUpdate(

               { "name" : "Google" },

               { $set: { "name" : "google"} },

               { sort: { "name" : 1 }, upsert:true, returnNewDocument : true }

            );


         Output:

            { "_id" : ObjectId("5a981ed7cf26fba5c0340b10"), "name" : "google" }


w.r.t.  findAndModify & update,update first fetch the item first and then updates it unlike 'findAndModify'.If we fetch an item and then update it, there may be an update by another thread between those two steps. If you update an item first and then fetch it, there may be another update in-between and you will get back a different item than what you updated.Doing it "atomically" means you are guaranteed that you are getting back the exact same item you are updating - i.e. no other operation can happen in between this is ensured by 'findAndModify',also 'findAndModify' returns the document, update does not.    Furthermore 'findAndModify' is deprecated for 'findOneAndUpdate'.

4) _id Primary Key of document:
Each document we insert into collection get additional field called _id which is combination of timestamp,machine key & process id & some additional binary number.But if you insert a document with _id field then default field get overwritten.

    Query:
        db.crudops.insert({_id:5}) and 
        db.crudops.insert({id:5})
    output:
        { "_id" : ObjectId("5a98dbb7b819cf73e0a44af1"), "id" : 5 }
        { "_id" : 5 }

5) deleteOne:
    Record to Delete:
        { "_id" : 5 }
    Query:
        db.crudops.deleteOne({"_id" : 5});
    Output:
        { "acknowledged" : true, "deletedCount" : 1 }


deleteOne deletes the first document that matches the filter. Need tp use a field that is part of a unique index such as _id for precise deletions.
    deleteOne() throws a WriteError exception if used on a capped collection. To remove documents from a capped collection, use db.collection.drop() instead.

6) deleteMany:
    deleteMany() also throws a WriteError exception if used on a capped collection. To remove all documents from a capped collection, use db.collection.drop() instead.

    Query:
    try {
       db.crudops.deleteMany( { "display" : "AMOLED" } );
    } catch (e) {
       print (e);
    }
    Output:
    { "acknowledged" : true, "deletedCount" : 2 }

    Here following two document get deleted
    {
        "_id" : ObjectId("5a9812c839eb5b1254451ec9"),
        "name" : "Google Pixel 2",
        "ram" : 4,
        "os" : "Oreo",
        "company" : "google",
        "display" : "AMOLED"
    }
    {
        "_id" : ObjectId("5a9812fa39eb5b1254451eca"),
        "name" : "Google Pixel XL",
        "ram" : 4,
        "os" : "Oreo",
        "company" : "Google INC",
        "display" : "AMOLED"
    }

7) remove:
By default, remove() removes all documents that match the query expression. Specify the justOne option to limit the operation to removing a single document. To delete a single document sorted by a         specified order, use the findAndModify() method.

        Query:
            db.crudops.remove({"company": "samsung"},true)
        output:
            WriteResult({ "nRemoved" : 1 })

    to remove all document matching filter
   
        Query:
            db.crudops.remove({ company: "google" },false)
        Output:
            WriteResult({ "nRemoved" : 8 })


     using 'findAndModify' to remove
    lets add some documents
        db.crudops.insert({"company":"google","sortindex":"1"});
        db.crudops.insert({"company":"google","sortindex":"2"});
        db.crudops.insert({"company":"google","sortindex":"3"});
        db.crudops.insert({"company":"google","sortindex":"4"});
        db.crudops.insert({"company":"google","sortindex":"5"});
        db.crudops.insert({"company":"google","sortindex":"6"});

    Query:
        db.crudops.findAndModify({
            query: { company: "google" },
            sort: { sortindex: 1 },
            remove: true,
            upsert:false
        })
    output:
        {
            "_id" : ObjectId("5a98e1cdb819cf73e0a44af2"),
            "company" : "google",
            "sortindex" : "1"
        }

    Here records get sorted by sortindex then first record is removed.

8) findOneAndDelete:
It deletes a single document based on the filter and sort criteria, returning the deleted document.
   
    Query:
        db.crudops.findOneAndDelete(
            { "company" : "google" },
            { sort : { "sortindex" : -1 } }
        )
    output:
        {
            "_id" : ObjectId("5a98e1f7b819cf73e0a44af5"),
            "company" : "google",
            "sortindex" : "4"
        }   

    Here also one record deleted but sort order specified is descending.

findOneAndDelete() returns the deleted document after having deleted it in case you need its contents after the delete operation.
    deleteOne() is used to delete a single document while remove() is a deprecated function and has been replaced by deleteOne() to delete a single document and deleteMany() to delete multiple documents.

9) findOneAndReplace:
    Query:
        db.crudops.findOneAndReplace(
           { "company" : "google" },
           { "display" : "AMOLED", "Ram" : 4 },
           { sort: { "sortindex" : 1 } }
        )
    Output:
        It return document before update
        {
            "_id" : ObjectId("5a98e1d3b819cf73e0a44af3"),
            "company" : "google",
            "sortindex" : "2"
        }

    after this update the updated document is

        {
            "_id" : ObjectId("5a98e1d3b819cf73e0a44af3"),
            "display" : "AMOLED",
            "Ram" : 4
        }
    the filter field also get removed as not specified in replace string

    returning updated document in findOneAndReplace:

    Query:
        db.crudops.findOneAndReplace(
           { "company" : "google" },
           { "company" : "google","display" : "AMOLED", "Ram" : 40 },
           { sort: { "sortindex" : 1 },returnNewDocument:true}
        )
    Output:
        {
            "_id" : ObjectId("5a98e1f4b819cf73e0a44af4"),
            "company" : "google",
            "display" : "AMOLED",
            "Ram" : 40
        }

    complete document after update is
        {
            "_id" : ObjectId("5a98e1f4b819cf73e0a44af4"),
            "company" : "google",
            "display" : "AMOLED",
            "Ram" : 40
        }

10) insertmany:
    Given an array of documents, insertMany() inserts each document in the array into the collection.By default documents are inserted in order.If ordered is set to false, documents are inserted in an unordered format and may be reordered by mongod to increase performance.
   
    Query:
        db.crudops.insertMany(
            [
                {"company":"google","sortindex":"7"},
                {"company":"google","sortindex":"8"},
                {"company":"google","sortindex":"9"}
            ],
            { ordered: false }
        );
    Output:
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5a98e8cdb819cf73e0a44af8"),
            ObjectId("5a98e8cdb819cf73e0a44af9"),
            ObjectId("5a98e8cdb819cf73e0a44afa")
        ]
    }   

   we can insert primary key _id field also

    db.crudops.insertMany(
            [
                {"company":"google","sortindex":10,_id: 10},
                {"company":"google","sortindex":11,_id: 11},
                {"company":"google","sortindex":12,_id: 12}
            ],
            { ordered: false }
        );
    output:
        { "acknowledged" : true, "insertedIds" : [ 10, 11, 12 ] }

    db.crudops.insertMany(
            [
                {"company":"google","sortindex":10,_id: 12},
                {"company":"google","sortindex":11,_id: 13},
                {"company":"google","sortindex":12,_id: 14}
            ],
            { ordered: false }
        );

Here we are trying to insert a duplicate key in _id with 12 which resulted in error but remaining two records get inserted.so you can find following records despite error as these two record does not violate any constraint as such.

        {"company":"google","sortindex":11,_id: 13},
        {"company":"google","sortindex":12,_id: 14}

Error message for first record is "E11000 duplicate key error collection: Northwind.crudops index: _id_ dup key: { : 12.0 }".

Note:To clear mongo console you can use 'cls' command.

No comments:

Post a Comment