4

Let's say I've got this structure:

{
    "_id" : ObjectId("52af7c1497bcaf410e000002"),
    "created_at" : ISODate("2013-12-16T22:17:56.219Z"),
    "name" : "Hot",
    "subcategories" : {
        "Loco" : {
            "subcategory" : "Loco",
                "id" : "522423de-fffe-44be-ed3b-93fdd50fdb4f",
                "products" : [ ]
        },
        "Loco2" : {
            "subcategory" : "Loco2",
                "id" : "522423de-fffe-44be-ed3b-93fdd50fd55",
                "products" : [ ]
        },
    }
}

How can I remove Loco2 from within subcategories leaving everything else intact?

Please note that my object selector got be the ObjectId as there will be other documents that have the structure with possibly the same subcategories name that belongs to different documents. For instance, I could also have another object like this:

{
    "_id" : ObjectId("52af7c1497bcaf410e000003"),
    "created_at" : ISODate("2013-12-16T22:17:56.219Z"),
    "name" : "Medium",
    "subcategories" : {
        "Loco" : {
            "subcategory" : "Loco",
                "id" : "522423de-fffe-44be-ed3b-93fdd50332b4f",
                "products" : [ ]
        },
        "Loco2" : {
            "subcategory" : "Loco2",
                "id" : "522423de-fffe-44be-ed3b-93fdd522d55",
                "products" : [ ]
        },
    }
}

So my query should be along those lines: db.categories.update({"_id": "ObjectId("52af7c1497bcaf410e000003")"}, {don't know this part yet})

EDIT: The answer did work on the shell when I know the name of the subcategory I want to delete, however I couldn't get it to work within my Node app:

    Categories.prototype.delSubcategory = function(categoryId, subcategory, callback) {

    this.getCollection(function(error, category_collection) {

        if(error) callback(error);

        else {

            category_collection.update(

                {_id: category_collection.db.bson_deserializer.ObjectID.createFromHexString(categoryId)},
                { $unset : { "subcategories.Loco2: "" } },
                function(error, subcategory) {

                    if(error) callback(error);

                    else callback(null, subcategory)

                }

            )

        }

    });

};
WagnerMatosUK
  • 4,309
  • 7
  • 56
  • 95

1 Answers1

6

You can use the $unset operator to remove fields from a document or its sub-objects.

db.collection_name.update(
      {"_id": ObjectId("52af7c1497bcaf410e000003")}, 
      { $unset : { "subcategories.Loco2" : "" } }
);
mnemosyn
  • 45,391
  • 6
  • 76
  • 82
Philipp
  • 67,764
  • 9
  • 118
  • 153
  • I've tried that but it isn't working. When I tried using the shell, I got this error: SyntaxError: Unexpected token ILLEGAL – WagnerMatosUK Dec 17 '13 at 07:38
  • There's a syntax error in @Philipp's answer, it should read `{"_id": ObjectId("52af7c1497bcaf410e000003") }`, i.e. no quotation marks. You have to invoke a constructor that creates an `ObjectId` from a `string`. – mnemosyn Dec 17 '13 at 08:27
  • Yeap, I've tried again and it did work on the shell. One question though: how can I get the make the Loco2 in "subcategories.Loco2" as a variable in my Node application? I've tried `"subcategories" + myVar: ""` and it didn't work. Neither "subcategories.myVar". The full is this: – WagnerMatosUK Dec 17 '13 at 13:53