简体   繁体   中英

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

On MongoDB v 4.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" : []
                }
            }
        ]
    }
}

Just use . to create a new object key.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM