burdk
burdk

Reputation: 81

How to add attribute to all documents in a collection, with same data of another attribute in MongoDB?

I've seen this question and it could be useful, but I need some extra steps.

I have a collection of Sites filled with name, data and a field called infoBox that is an object.

infoBox: {
    coordX: {
      type: Number,
    },
    coordY: {
      type: Number,
    },
    type: {
      type: Number,
      enum: [InfoBoxType.line, InfoBoxType.horizontal, InfoBoxType.vertical],
    },
    midPoint: {
      coordX: {
        type: Number,
      },
      coordY: {
        type: Number,
      },
    },

So, I need to add another attibute to all infoboxes of the sites called "levels" that is an array, and this field must contains two objects like InfoBox, with the same values, but with empty 'levels'. (both infobox 1 & 2 with same values).This is to initialize the DB, later these values will be editted by the users.

Trying to be clear, I actually have:

Site
    data
    name
    infobox
        coordx
        coordy
        midpoint
            coordx
            coordy

and I need

Site 
    data
    name
    infobox
        coordx
        coordy
        midpoint
            coordx
            coordy
        levels  
            infobox1
                coordx
                coordy
                midpoint
                    coordx
                    coordy
                levels(empty)
            infobox2
                coordx
                coordy
                midpoint
                    coordx
                    coordy
                levels(empty)

How can I accomplish this?

Extra info: Mongo version 4.2

EDIT

I am trying to make it with something like this, but with no luck yet:

let sites = await this.siteModel.find({});
 const firstZoom = site.infoBox;
 const secondZoom =  site.infoBox;

  const levelss = [
    firstZoom,
    secondZoom,
  ];

await this.siteModel.update({ _id: site._id }, { $set: { 'infoBox.levels.$': levelss } });

Upvotes: 1

Views: 855

Answers (2)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

On MongoDB v4.2 which supports aggregation pipeline in update operations, you can try this (you can use .updateMany() as well) :

this.siteModel.update({},
    [{
        $set: {
            'infobox.levels': [{ infobox1: { $mergeObjects: ['$infobox', { 'levels': [] }] } },
            { infobox2: { $mergeObjects: ['$infobox', { 'levels': [] }] } }]
        }
    }], { multi: true })

Ref : .update()

Collection Data :

/* 1 */
{
    "_id" : ObjectId("5e4dba9e7f8bc30a75c658fc"),
    "data" : 1,
    "name" : "noName",
    "infobox" : {
        "coordx" : 2,
        "coordy" : 2,
        "midpoint" : {
            "coordx" : 1,
            "coordy" : 1
        }
    }
}

/* 2 */
{
    "_id" : ObjectId("5e4dbab07f8bc30a75c65ab1"),
    "data" : 2,
    "name" : "yesName",
    "infobox" : {
        "coordx" : 4,
        "coordy" : 4,
        "midpoint" : {
            "coordx" : 2,
            "coordy" : 2
        }
    }
}

Docs in DB after update operation :

/* 1 */
{
    "_id" : ObjectId("5e4dba9e7f8bc30a75c658fc"),
    "data" : 1,
    "name" : "noName",
    "infobox" : {
        "coordx" : 2,
        "coordy" : 2,
        "midpoint" : {
            "coordx" : 1,
            "coordy" : 1
        },
        "levels" : [ 
            {
                "infobox1" : {
                    "coordx" : 2,
                    "coordy" : 2,
                    "midpoint" : {
                        "coordx" : 1,
                        "coordy" : 1
                    },
                    "levels" : []
                }
            }, 
            {
                "infobox2" : {
                    "coordx" : 2,
                    "coordy" : 2,
                    "midpoint" : {
                        "coordx" : 1,
                        "coordy" : 1
                    },
                    "levels" : []
                }
            }
        ]
    }
}

/* 2 */
{
    "_id" : ObjectId("5e4dbab07f8bc30a75c65ab1"),
    "data" : 2,
    "name" : "yesName",
    "infobox" : {
        "coordx" : 4,
        "coordy" : 4,
        "midpoint" : {
            "coordx" : 2,
            "coordy" : 2
        },
        "levels" : [ 
            {
                "infobox1" : {
                    "coordx" : 4,
                    "coordy" : 4,
                    "midpoint" : {
                        "coordx" : 2,
                        "coordy" : 2
                    },
                    "levels" : []
                }
            }, 
            {
                "infobox2" : {
                    "coordx" : 4,
                    "coordy" : 4,
                    "midpoint" : {
                        "coordx" : 2,
                        "coordy" : 2
                    },
                    "levels" : []
                }
            }
        ]
    }
}

Upvotes: 1

mrblue
mrblue

Reputation: 237

Just use . to create a new object key.

Site.levels = {}
Site.levels.infobox1 = Site.infobox
Site.levels.infobox2 = Site.infobox

Upvotes: 0

Related Questions