I've imported a table containing a self referencing parent/child relationship into a class in Parse.com. Parse creates a new ID which I would now like to replace the UID with. I cannot seem to update all of the corresponding parent ID fields.
I've almost managed to get it going with some cloud code:
Parse.Cloud.define("updatePID", function(request, response) {
var _results={};
var query = new Parse.Query("ww_notes");
query
.limit(1000)
.find({
success: function(results){
for (var i=0; i<results.length; i++){
_results[results[i].get("uid")] = results[i].id;
};
for (var i=0; i<results.length; i++){
if (_results[results[i].get("pid")]){
results[i].set("test", _results[results[i].get("pid")]);
results[i].save();
};
};
response.success(results);
},
error: function(){
response.error("failed PID update");
}
});
})
This returns the corrected recordset but doesn't save it in the database. Note: test is just a test field to get this function working before switching to updating the PID. I've tried to simplify the problem by moving a static write into the first loop:
for (var i=0; i<results.length; i++){
_results[results[i].get("uid")] = results[i].id;
results[i].set("test", "things");
results[i].save();
};
This only updated 4 of 245 records. The recordset sent back was correctly updated but the Parse data store was not. I've created an equivalent job which resulted in 27 of the 245 records being updated. The job returned successfully.
Stephen
The problem you're having is almost certainly related to how you handle the asynch saves.
The reason you're getting only a few saves does is that the code launches them off asynchronously in a tight loop, then returns. You're getting a few saves done while the loop is finishing, then no more once you run response.
whatever.
The fix is to batch the saves and use promises like this...
// ...
query.limit(1000);
query.find().then(function(results) {
for (var i=0; i<results.length; i++){
_results[results[i].get("uid")] = results[i].id;
};
// we'll save everything in this array
var toSave = [];
for (var i=0; i<results.length; i++){
if (_results[results[i].get("pid")]){
results[i].set("test", _results[results[i].get("pid")]);
toSave.push(results[i]);
};
};
// return a promise that's complete when everything is saved
return Parse.Object.saveAll(toSave);
}).then(function(results) {
response.success(results);
}, function(error) {
response.error(error);
});