Hello, I have a class in my database that accumulates a lot of saved entries extremely quickly I would like to only keep a portion of the entries and remove all the entries from the table without deleting the entire table to retain the most recent 100 entries for example. I would like to delete these rows from a cloud function using a beforeSave trigger. I canât seem to figure out how to get a total count of entries within the class and then remove the amount over my limit. I canât seem to locate the correct solution to my problem with the docs.
Hey @ibn5x
Iâve prepaired an example. It removes all rows before creating new(address - is a filter):
Moralis.Cloud.beforeSave("ItemsOnSale", async function(request) {
const query = new Moralis.Query("Example");
const address = request.object.get("address");
query.equalTo("address", address );
const objects = await query.find({ useMasterKey: true });
for (let object of objects) {
if (object) {
await objects.destroy(null, {useMasterKey:true}).then(
() => {
logger.info("success");
},
(error) => {
logger.info(error);
}
);
}
}
});
In your case you also need to get length of objects array:
if (objects.lenth > 100) {
for (let i = 100; i < objects.l; i++) {
objects[i].destroy(null, {useMasterKey:true})
}
}
I really appreciate you taking the time to help me. I know this is simple, and I can query and add to Moralis just fine, still, Iâm unable to perform this task of filtering, and constraining, then calling a trigger to remove the above threshold entries beforeSave. I hate to admit it, but Iâve spent the better half of three hours, trying still not the desired result. So itâs clear I donât understand looking at my cloud function can you see anything that stands out that Iâm overlooking?
cloud function
Moralis.Cloud.beforeSave("PlayerPosition", async function(request) {
const query = new Moralis.Query("PlayerPosition");
const Player = request.object.get("ethAddress");
query.equalTo("player", Player );
const objects = await query.find({ useMasterKey: true });
if(objects.length > 100){
for(let i = 100; i < objects.length; i++) {
objects[i].destroy(null, {useMasterKey:true}).then(
() => {
logger.info("success");
},
(error) => {
logger.info(error);
}
);
}
}
});
Hi,
What doesnât work as expected, or what error you have if you have an error?
I would try something like this to get more information of what is going on:
Moralis.Cloud.beforeSave("PlayerPosition", async function(request) {
const query = new Moralis.Query("PlayerPosition");
const Player = request.object.get("ethAddress");
query.equalTo("player", Player );
const objects = await query.find({ useMasterKey: true });
logger.info(objects.length);
if(objects.length > 100){
logger.info("more than 100 objects");
for(let i = 100; i < objects.length; i++) {
await objects[i].destroy(null, {useMasterKey:true});
}
}
});
well the functionality Iâm going for requires a trigger beforeSave that checks the length of the entries within the table and if it exceeds 100 entries empty the table retaining only the most recent 100 entries. I canât seem to wrap my head around this concept currently I have the following code which still doesnât function. It continuously allows for the accumulation of entries, which points me in the direction that my method for constraining my query is incorrect, but Iâm in no position to make suggestions.
error in Moralis console state : Error: Invalid function: âplayerPositionâ (Iâve tried to address this with no success)
current cloud function
Moralis.Cloud.beforeSave("PlayerPosition", async function(request) {
const query = new Moralis.Query("PlayerPosition");
const player = request.object.get("ethAddress");
query.equalTo("player", player);
const objects = await query.find({ useMasterKey: true });
if(objects.length > 100){
for(let i = 100; i < objects.length; i++) {
objects[i].destroy(null, {useMasterKey:true}).then(
() => {
logger.info("success");
},
(error) => {
logger.info(error);
}
);
}
}
});
Error: Invalid function: âplayerPositionâ
usually means that it has a syntax error.
will give it a shot unfortunately Iâve gotten no sleep Iâm crashing, shall try it with a fresh set of eyes in a couple of hours or so. Thank you for your time and suggestion. I will report back.
Are you trying to run âPlayerPositionâ? Itâs not a cloud function
For me it looks like you trying to start âPlayerPositionâ using Parse.Cloud.run(âPlayerPositionâ). But itâs a befoSave trigger, not a function
finally awaken. I implemented your suggestion but nothing outputs to the Moralis console. In the google chrome console I now have a failed websocket error. Im combing through my syntax now but I have not come across the error. I will keep at it.
No, Iâm only calling it server-side. Although against the advice of the docs I did attempt to call it from the client-side out of frustration a few times before coming to the forum (something like await Moralis.Cloud.run(âplayerPositionâ); which of course did not work.
cloud function
Moralis.Cloud.beforeSave("playerPosition", async function(request) {
const query = new Moralis.Query("PlayerPosition");
const Player = request.object.get("ethAddress");
query.equalTo("player", Player);
const objects = await query.find({ useMasterKey: true });
logger.info(objects.length);
if(objects.length > 100){
logger.info("more than 100 objects");
for(let i = 100; i < objects.length; i++) {
await objects[i].destroy(null, {useMasterKey:true})
}
}
});
in this case, you may want to use Moralis.Cloud.define
instead of Moralis.Cloud.beforeSave
and call this cloud function directly when you want to remove old entries.
Now, this is odd. Iâm not sure what Iâm doing wrong. I took your advice and opted to just define a cloud function and call it every time my user quit the app. Since I was unable to constrain my query properly I decided to jump everything and keep none. Still nothing, I attempted to try and see what was going on with a few console logs but everything fires off as expected except the table does not âdumpâ. Iâm stumped
defining cloud
Moralis.Cloud.define("playerposition", async function(request) {
const PlayerQuery = new Moralis.Query("PlayerPosition");
//const Player = request.object.get("player");
//PlayerQuery.equalTo("player", Player);
const objects = await PlayerQuery.find();
for(let i = 0; i < objects.length; i++) {
await objects[i].destroy(null, {useMasterKey:true});
return 'inside, should be dumped!';
}
return 'entries Dumped!';
});
calling from clientâŚ
async function dumpPositions() {
const dumpIt = await Moralis.Cloud.run("playerposition");
console.log("positions dumped");
console.log(dumpIt);
}
Im calling the above function from within my logic for game over
async function hitAave(player, aave) {
let user = Moralis.User.current();
this.physics.pause();
player.setTint(0xff0000);
player.anims.play('turn');
let highscore = score;
const HighScore = Moralis.Object.extend("HighScore");
const highScore = new HighScore();
highScore.set('player', user.get('ethAddress'));
highScore.set('score', highscore);
const RaidHistory = Moralis.Object.extend("RaidHistory");
const raiderHistory = new RaidHistory();
raiderHistory.set('player', user.get('ethAddress'));
raiderHistory.set('score', highscore);
raiderHistory.set('level', levelReached);
raiderHistory.set('AavegotchiAnger', angerLevel);
await highScore.save();
await raiderHistory.save();
dumpPositions();
console.log("score " + " " + highscore);
console.log("score " + " " + raiderHistory);
gameOver = true;
}
I appreciate everyoneâs patience and assistance, I was finally able to weed out the error with some assistance from you all and finally with @Yomoo coming through for the kill and focusing my direction. I love it here again really appreciate you all assisting me. Iâm back to building.
Any chance you can post a snippet of your working code?