Skip to content

Commit a9e73c9

Browse files
authored
Update delete_custom_events.js
1 parent 5b5c53a commit a9e73c9

File tree

1 file changed

+134
-131
lines changed

1 file changed

+134
-131
lines changed

bin/scripts/expire-data/delete_custom_events.js

Lines changed: 134 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -2,134 +2,137 @@
22
* Description: Deletes obsolete custom events (not received for >90 days) from Countly and Drill DBs for an app.
33
* Usage: node delete_x_days_inactive_events.js
44
*/
5-
const { ObjectId } = require('mongodb');
6-
const pluginManager = require('../../../plugins/pluginManager.js');
7-
const common = require('../../../api/utils/common.js');
8-
const drillCommon = require('../../../plugins/drill/api/common.js');
9-
//double-check below details before running the script
10-
const DRY_RUN = true; // Set to false to actually delete
11-
const APP_ID = ""; // Replace with your app's ObjectID string
12-
const DAYS = 90; // Number of days for active events
13-
function daysAgo(days) {
14-
return Math.floor(Date.now() / 1000) - days * 24 * 60 * 60; // eventTimes uses Unix timestamps (seconds)
15-
}
16-
Promise.all([pluginManager.dbConnection("countly"), pluginManager.dbConnection("countly_drill")]).then(async function([countlyDb, drillDb]) {
17-
console.log("Connected to databases...");
18-
common.db = countlyDb;
19-
common.drillDb = drillDb;
20-
try {
21-
const app = await countlyDb.collection("apps").findOne({_id: new ObjectId(APP_ID)}, {_id: 1, name: 1});
22-
if (!app) {
23-
console.log("App not found");
24-
return close();
25-
}
26-
console.log("App:", app.name);
27-
// Get eventTimes data
28-
const eventTimesColl = "eventTimes" + APP_ID;
29-
const allDocs = await countlyDb.collection(eventTimesColl).find({}).toArray();
30-
31-
let obsoleteEvents = [];
32-
if (allDocs.length) {
33-
for (const doc of allDocs) {
34-
if (doc.e && Array.isArray(doc.e)) {
35-
for (const eventObj of doc.e) {
36-
// eventObj.e is event key, eventObj.ts is last timestamp (Unix seconds)
37-
if (eventObj.t && Math.floor(eventObj.t / 1000) < daysAgo(DAYS)) {
38-
obsoleteEvents.push(eventObj.e);
39-
}
40-
}
41-
}
42-
}
43-
}
44-
obsoleteEvents = [...new Set(obsoleteEvents)];
45-
console.log("Obsolete events to delete:", obsoleteEvents);
46-
if (DRY_RUN) {
47-
console.log("DRY_RUN enabled. No changes will be made.");
48-
return close();
49-
}
50-
if (!obsoleteEvents.length) {
51-
return close("No obsolete events to delete");
52-
}
53-
// Delete obsolete events
54-
await deleteDrillEvents(app._id, obsoleteEvents);
55-
await deleteCountlyEvents(app._id, obsoleteEvents);
56-
await deleteEventTimes(app._id, obsoleteEvents);
57-
await deleteEventGroups(app._id, obsoleteEvents);
58-
await deleteEventKeys(app._id, obsoleteEvents);
59-
close();
60-
61-
} catch (err) {
62-
console.log("App not found or error occurred");
63-
close(err);
64-
}
65-
async function deleteDrillEvents(appId, events) {
66-
for (let i = 0; i < events.length; i++) {
67-
var collectionName = drillCommon.getCollectionName(events[i], appId);
68-
try {
69-
await drillDb.collection(collectionName).drop();
70-
console.log("Dropped Drill collection:", collectionName);
71-
} catch (ex) {
72-
// Collection may not exist
73-
console.log("Could not drop collection (may not exist):", collectionName);
74-
}
75-
}
76-
//delete from aggregated drill event collection
77-
await drillDb.collection('drill_events').deleteMany({'a': appId + "", 'e': {$in: events}});
78-
console.log("Cleared from drill_events");
79-
await drillDb.collection('drill_bookmarks').deleteMany({'app_id': appId, 'event_key': {$in: events}});
80-
console.log("Cleared drill_bookmarks");
81-
await drillDb.collection("drill_meta").deleteMany({'app_id': (appId + ""), "type": "e", "e": {$in: events}});
82-
console.log("Cleared drill_meta");
83-
}
84-
async function deleteCountlyEvents(appId, events) {
85-
for (let i = 0; i < events.length; i++) {
86-
var collectionName = 'events' + drillCommon.getEventHash(events[i], appId);
87-
try {
88-
await countlyDb.collection(collectionName).drop();
89-
console.log("Dropped Countly collection:", collectionName);
90-
} catch (ex) {
91-
// Collection may not exist
92-
console.log("Could not drop collection (may not exist):", collectionName);
93-
}
94-
//clear from merged collection
95-
await countlyDb.collection("events_data").deleteMany({'_id': {"$regex": "^" + appId + "_" + drillCommon.getEventHash(events[i], appId) + "_.*"}});
96-
console.log("Cleared from aggregated events_data for:", events[i]);
97-
}
98-
}
99-
async function deleteEventTimes(appId, events) {
100-
await countlyDb.collection("eventTimes" + appId).updateMany({}, {"$pull": {"e": {"e": {$in: events}}}});
101-
console.log("Cleared eventTimes");
102-
await countlyDb.collection("timelineStatus").deleteMany({'app_id': (appId + ""), "event": {$in: events}});
103-
console.log("Cleared timelineStatus");
104-
}
105-
async function deleteEventKeys(appId, events) {
106-
const unsetQuery = {};
107-
for (let i = 0; i < events.length; i++) {
108-
unsetQuery[`segments.${events[i]}`] = "";
109-
unsetQuery[`map.${events[i]}`] = "";
110-
unsetQuery[`omitted_segments.${events[i]}`] = "";
111-
}
112-
// Remove from "list" and "overview" arrays, and unset event segments/maps
113-
await countlyDb.collection("events").updateOne(
114-
{_id: appId},
115-
{
116-
$pull: {
117-
list: {$in: events},
118-
overview: {eventKey: {$in: events}}
119-
},
120-
$unset: unsetQuery
121-
}
122-
);
123-
console.log("Cleared events:", events);
124-
}
125-
async function deleteEventGroups(appId, events) {
126-
await countlyDb.collection("event_groups").updateMany({'app_id': (appId + "")}, {"$pull": {"source_events": {$in: events}}});
127-
console.log("Cleared event_groups");
128-
}
129-
function close(err) {
130-
if (err) console.log("Finished with errors:", err);
131-
else console.log("Finished successfully.");
132-
countlyDb.close();
133-
drillDb.close();
134-
}
135-
});
5+
const { ObjectId } = require('mongodb');
6+
const pluginManager = require('../../../plugins/pluginManager.js');
7+
const common = require('../../../api/utils/common.js');
8+
const drillCommon = require('../../../plugins/drill/api/common.js');
9+
// double-check below details before running the script
10+
const DRY_RUN = true; // Set to false to actually delete
11+
const APP_ID = ""; // Replace with your app's ObjectID string
12+
const DAYS = 90; // Number of days for active events
13+
function daysAgo(days) {
14+
// eventTimes uses Unix timestamps (seconds)
15+
return Math.floor(Date.now() / 1000) - days * 24 * 60 * 60;
16+
}
17+
Promise.all([pluginManager.dbConnection("countly"), pluginManager.dbConnection("countly_drill")]).then(async function([countlyDb, drillDb]){
18+
console.log("Connected to databases...");
19+
common.db = countlyDb;
20+
common.drillDb = drillDb;
21+
try {
22+
const app = await countlyDb.collection("apps").findOne({ _id: new ObjectId(APP_ID) }, { _id: 1, name: 1 });
23+
if (!app) {
24+
console.log("App not found");
25+
return close();
26+
}
27+
console.log("App:", app.name);
28+
// Get eventTimes data
29+
const eventTimesColl = "eventTimes" + APP_ID;
30+
const allDocs = await countlyDb.collection(eventTimesColl).find({}).toArray();
31+
32+
let obsoleteEvents = [];
33+
if (allDocs.length) {
34+
for (const doc of allDocs) {
35+
if (doc.e && Array.isArray(doc.e)) {
36+
for (const eventObj of doc.e) {
37+
// eventObj.e is event key, eventObj.ts is last timestamp (Unix seconds)
38+
if (eventObj.t && Math.floor(eventObj.t / 1000) < daysAgo(DAYS)) {
39+
obsoleteEvents.push(eventObj.e);
40+
}
41+
}
42+
}
43+
}
44+
}
45+
obsoleteEvents = [...new Set(obsoleteEvents)];
46+
console.log("Obsolete events to delete:", obsoleteEvents);
47+
if (DRY_RUN) {
48+
console.log("DRY_RUN enabled. No changes will be made.");
49+
return close();
50+
}
51+
if (!obsoleteEvents.length) {
52+
return close("No obsolete events to delete");
53+
}
54+
// Delete obsolete events
55+
await deleteDrillEvents(app._id, obsoleteEvents);
56+
await deleteCountlyEvents(app._id, obsoleteEvents);
57+
await deleteEventTimes(app._id, obsoleteEvents);
58+
await deleteEventGroups(app._id, obsoleteEvents);
59+
await deleteEventKeys(app._id, obsoleteEvents);
60+
close();
61+
} catch (err) {
62+
console.log("App not found or error occurred");
63+
close(err);
64+
}
65+
async function deleteDrillEvents(appId, events) {
66+
for (let i = 0; i < events.length; i++) {
67+
var collectionName = drillCommon.getCollectionName(events[i], appId);
68+
try {
69+
await drillDb.collection(collectionName).drop();
70+
console.log("Dropped Drill collection:", collectionName);
71+
} catch (ex) {
72+
// Collection may not exist
73+
console.log("Could not drop collection (may not exist):", collectionName);
74+
}
75+
}
76+
// delete from aggregated drill event collection
77+
await drillDb.collection('drill_events').deleteMany({ 'a': appId + "", 'e': { $in: events } });
78+
console.log("Cleared from drill_events");
79+
await drillDb.collection('drill_bookmarks').deleteMany({ 'app_id': appId, 'event_key': { $in: events } });
80+
console.log("Cleared drill_bookmarks");
81+
await drillDb.collection("drill_meta").deleteMany({ 'app_id': (appId + ""), "type": "e", "e": { $in: events } });
82+
console.log("Cleared drill_meta");
83+
}
84+
async function deleteCountlyEvents(appId, events) {
85+
for (let i = 0; i < events.length; i++) {
86+
var collectionName = 'events' + drillCommon.getEventHash(events[i], appId);
87+
try {
88+
await countlyDb.collection(collectionName).drop();
89+
console.log("Dropped Countly collection:", collectionName);
90+
} catch (ex) {
91+
// Collection may not exist
92+
console.log("Could not drop collection (may not exist):", collectionName);
93+
}
94+
// clear from merged collection
95+
await countlyDb.collection("events_data").deleteMany({ '_id': { "$regex": "^" + appId + "_" + drillCommon.getEventHash(events[i], appId) + "_.*" } });
96+
console.log("Cleared from aggregated events_data for:", events[i]);
97+
}
98+
}
99+
async function deleteEventTimes(appId, events) {
100+
await countlyDb.collection("eventTimes" + appId).updateMany({}, { "$pull": { "e": { "e": { $in: events } } } });
101+
console.log("Cleared eventTimes");
102+
await countlyDb.collection("timelineStatus").deleteMany({ 'app_id': (appId + ""), "event": { $in: events } });
103+
console.log("Cleared timelineStatus");
104+
}
105+
async function deleteEventKeys(appId, events) {
106+
const unsetQuery = {};
107+
for (let i = 0; i < events.length; i++) {
108+
unsetQuery[`segments.${events[i]}`] = "";
109+
unsetQuery[`map.${events[i]}`] = "";
110+
unsetQuery[`omitted_segments.${events[i]}`] = "";
111+
}
112+
// Remove from "list" and "overview" arrays, and unset event segments/maps
113+
await countlyDb.collection("events").updateOne(
114+
{ _id: appId },
115+
{
116+
$pull: {
117+
list: { $in: events },
118+
overview: { eventKey: { $in: events } }
119+
},
120+
$unset: unsetQuery
121+
}
122+
);
123+
console.log("Cleared events:", events);
124+
}
125+
async function deleteEventGroups(appId, events) {
126+
await countlyDb.collection("event_groups").updateMany({ 'app_id': (appId + "") }, { "$pull": { "source_events": { $in: events } } });
127+
console.log("Cleared event_groups");
128+
}
129+
function close(err) {
130+
if (err) {
131+
console.log("Finished with errors:", err);
132+
} else {
133+
console.log("Finished successfully.");
134+
}
135+
countlyDb.close();
136+
drillDb.close();
137+
}
138+
});

0 commit comments

Comments
 (0)