0

I need to change my schema

const dataSchema = new Schema({
  trackingPrice: [{
    timeCheck: { type: Date, default: Date.now },
    lowestPrice: Number,
    salePrice: Number,
    saleRank: Number
  }]
})

to this

const dataSchema = new Schema({
  trackingPrice: [{
    timeCheck: { type: Date, default: Date.now },
    lowestPrice: Number,
    salePrice: Number
  }],
  trackingRank: [{
    timeCheck: { type: Date, default: Date.now },
    saleRank: Number
  }]
})

How can I transfer my data from one to another under document and then delete "saleRank"?

chridam
  • 100,957
  • 23
  • 236
  • 235
jaribu
  • 115
  • 1
  • 11
  • Possible duplicate of https://stackoverflow.com/questions/3974985/ – chridam Feb 19 '18 at 11:47
  • Depends if this data is in production with a high rate of change. If not just find the record and manipulate the arrays and save the doc. If it is then better to use mongo's $set, $push etc commands which are transactional? – Dominic Feb 19 '18 at 11:56

2 Answers2

1

Based on this very good answer, the cursor in your case would be derived from running the aggregate pipeline:

const pipeline = [
    {
        "$project": {
            "trackingPrice": {
                "$map": {
                    "input": "$trackingPrice",
                    "as": "el",
                    "in": { 
                        "timeCheck": "$$el.timeCheck",
                        "lowestPrice": "$$el.timeCheck",
                        "salePrice": "$$el.salePrice"
                    }
                }
            },
            "trackingRank": {
                "$map": {
                    "input": "$trackingPrice",
                    "as": "el",
                    "in": { 
                        "timeCheck": "$$el.timeCheck",
                        "saleRank": "$$el.saleRank"
                    }
                }
            }
        }
    }
];

const cursor = Data.aggregate(pipeline).exec();

Running the bulk update:

let bulkUpdateOps = [];

cursor.then(results => {
    results.forEach(doc => {
        const { _id, trackingPrice, trackingRank } = doc;
        bulkUpdateOps.push({
            "updateOne": {
               "filter": { _id },
               "update": { "$set": { trackingPrice, trackingRank } },
               "upsert": true
            }
        });
    }); 

    if (bulkUpdateOps.length === 1000) {
        bulkUpdateOps = [];
        return Data.bulkWrite(bulkUpdateOps);           
    }       

}).then(console.log).catch(console.error);

if (bulkUpdateOps.length > 0) {
    Data.bulkWrite(bulkUpdateOps).then(console.log).catch(console.error);
}
chridam
  • 100,957
  • 23
  • 236
  • 235
0

The best way I see is to find all of them, and foreach one create a new one

I'm using mongoose by the way

    dataSchema.find({}, (err,all) => {
          var array = [];
          all.foreach( (ds) => {
            array.push({
              trackingPrice: ds.trackingPrice,
              trackingRank: //whatever way you want to update the old data
           })
           dataSchema.remove({}).exec(() => {
             array.foreach((a) => {
               var toadd = new dataSchema({
                   trackingPrice:a.trackingPrice,
                   trackingRank:a.trackingRank});
               toadd.save();                     
             })             
          })
       })}
    ); 
davdsb
  • 101
  • 1
  • 10