Search code examples
javascriptnode.jsmongodbdatabase-migrationmongoose-schema

How to migrate modify a collections of object array in mongodb?


I have the following schema mongoose, but have a app in production with collections. This is a simplification of a much larger problem, reduced for better understanding.

This is only a sample basic.

export const ListSchema = new Schema({
  listaItemsIds: [
    {
        type: Schema.Types.ObjectId,
        ref: 'Items',
        default: [],
    },
  ],
});

I need to migrate all the data to the following model.

export const ListSchema = new Schema({
  listaItemsIds: [
    {
      item: {
        type: Schema.Types.ObjectId,
        ref: 'Items',
        default: [],
      },
      property1: {
        type: Number,
        required: false,
        default: 0,
      },
      property2: {
        type: Number,
        required: false,
        default: 0,
      },
    },
  ],
});

The following document

{
        "_id" : ObjectId("62bade11ff94fb9e5a0f5236"),
        "listaItemsIds" : [
                ObjectId("62a118a9167d269d38a4c806"),
                ObjectId("62baef0cff94fb9e5a0f53e3"),
                ObjectId("627bb4d61119d5ce2201b7df")
        ],
        "__v" : 37
}

it is necessary to transform

{
        "_id" : ObjectId("62bade11ff94fb9e5a0f5236"),
        "listaItemsIds" : [
                {
                    item:ObjectId("62a118a9167d269d38a4c806"),
                    property1:55,
                    property2:75,
                },
                {
                    item:ObjectId("62baef0cff94fb9e5a0f53e3"),
                    property1:55,
                    property2:75,
                },
                {
                    item:ObjectId("627bb4d61119d5ce2201b7df"),
                    property1:55,
                    property2:75,
                },              
        ],
        "__v" : 37
}

I have tried the following code snippet with no results.

db.ListSchemas.updateMany({},
    [
    {$set: {"listaItemsIds.$[elem]":
    {
      item:"listaItemsIds.$[elem]",
      property1:0,
      property2:0,
    }}}
    ]
    );

Surely someone with more experience can help me.


Solution

  • Maybe something like this:

    db.collection.update({},
    [
    {
    $addFields: {
      listaItemsIds: {
        $map: {
          input: "$listaItemsIds",
          as: "id",
          in: {
              item: "$$id",
              property1: 55,
              property2: 75
             }
           }
         }
       }
     }
    ],
    {
      multi: true
    })
    

    Explained:

    Replace the array using $map to create the necessary objects.

    Playground