问题
I have created a background job to run every minute. The purpose of it is to delete old or outdated data within the database. In this case, the user submits a time which has an attached timestamp to it, and the two values are stored in arrays times
and timestamp
. So I wrote my cloud code to check if the times are older than an hour via their timestamps. If so, delete them from the database. However, that's the part I'm having trouble with. Here's my cloud code so you can see what's going on:
Parse.Cloud.job("expireTimes", function(request, response){
Parse.Cloud.useMasterKey();
var currentTime = new Date().getTime() / 1000;
var query = new Parse.Query("Wait");
query.find().then(function(results) {
var times = (results.length>0)? results[0].get("times") : "n/a";
var timestamps = (results.length>0)? results[0].get("timestamp") : "n/a";
console.log("Got " + results.length + " Times: " + times);
console.log("Got " + results.length + " Timestamps: " + timestamps);
for (var i = 0; i < timestamps.length; i++) {
if (currentTime >= timestamps[i] + 3600) {
// Delete old wait times
timestamps.splice(i, 1);
times.splice(i, 1);
i--;
} else {
break;
}
};
response.success("success");
}, function(error) {
response.error(error);
});
})
How do I update the database and delete the values within the array. Because when a user submits the time, it just adds to the times
array. Well, if I have the background job going every minute, some entries aren't going to be over an hour old. I want to keep those, but get rid of the other ones.
Any ideas? Any help is much appreciated. Thank you
回答1:
The essential part of the answer is that object properties can be set with set()
and objects are saved with save()
. Here's a quick example of just that...
// say object is some object that's been retrieved from the database
var times = object.get("times");
var timestamps = object.get("timestamp"); // would be better to make the array name plural in the database
// do whatever you want to the arrays here, then ...
object.set("times", times);
object.set("timestamp", timestamps);
return results[0].save();
}).then(function(result) {
response.success("success");
}, function(error) {
response.error(error);
});
But I understand you really want to do this for many Wait objects, so we're going to need a stronger design. Let's start getting into the habit of building functions that do logical chunks of work. Here's one that fixes those arrays for a given Wait object...
// delete parts of the waitObject time arrays prior to currentTime
function removeOldWaitTimes(waitObject, currentTime) {
var times = waitObject.get("times");
var timestamps = waitObject.get("timestamp");
for (var i = 0; i < timestamps.length; i++) {
if (currentTime >= timestamps[i] + 3600) {
// Delete old wait times
timestamps.splice(i, 1);
times.splice(i, 1);
i--;
} else {
break;
}
};
waitObject.set("times", times);
waitObject.set("timestamp", timestamps);
}
We need to call this in a loop, for each Wait object found. When we're done, we need to save all of the objects that were changed...
Parse.Cloud.job("expireTimes", function(request, response){
Parse.Cloud.useMasterKey();
var currentTime = new Date().getTime() / 1000;
var query = new Parse.Query("Wait");
query.find().then(function(results) {
for (var i=0; i<results.length; i++) {
removeOldWaitTimes(results[i], currentTime);
}
return Parse.Object.saveAll(results);
}).then(function(result) {
response.success("success");
}, function(error) {
response.error(error);
});
});
Please note that as the number of objects in the Wait class grows large, the job might get too long or the query (which can be set to a max limit of 1k objects returned) might miss results. We'll need to improve the query if that becomes a risk. (e.g. if the job runs every hour, there's no reason to retrieve Wait objects that were updated more than an hour ago).
EDIT say you want to update some as above, and destroy others. You'll need to handle two promises to do that...
Parse.Cloud.job("expireTimes", function(request, response){
Parse.Cloud.useMasterKey();
var destroyThese = [];
var currentTime = new Date().getTime() / 1000;
var query = new Parse.Query("Wait");
query.find().then(function(results) {
var updateThese = [];
for (var i=0; i<results.length; i++) {
var result = results[i];
if (result.get("times").length > 0) {
removeOldWaitTimes(result, currentTime);
updateThese.push(result);
} else {
destroyThese.push(result);
}
}
return Parse.Object.saveAll(updateThese);
}).then(function(result) {
return Parse.Object.destroyAll(destroyThese);
}).then(function(result) {
response.success("success");
}, function(error) {
response.error(error);
});
});
We place destroyThese array in the enclosing scope so that it is available to the next step in the chain of promises.
回答2:
Currently, i didn't find the best solution, but it's working for me now.
var Progress = Parse.Object.extend(PROGRESS);
var progressQuery = new Parse.Query(Progress);
progressQuery.equalTo("userId", userId)
progressQuery.find({
success: function (progress){
for (i = 0; i < progress.length; i++){
progress[i].set("lastUse", false)
progress[i].save()
}
},
error: function(object, error) {
console.log(error)
}
})
来源:https://stackoverflow.com/questions/33964017/parse-update-object-from-cloud-code