// findAppIdsCreatedSinceFriday.js
// Usage: MONGO_URI="mongodb://..." node findAppIdsCreatedSinceFriday.js
const { MongoClient } = require("mongodb");
(async () => {
const uri = process.env.MONGO_URI || "mongodb://localhost:27017";
const dbName = process.env.DB_NAME || "som";
const collName = process.env.COLL_NAME || "application";
// 🔒 Hardcode the Friday midnight you want
// If midnight in New York was intended and you're in EDT (UTC-4),
// use the equivalent UTC time (04:00:00Z).
// Example: Sep 19, 2025 00:00 in NYC -> 2025-09-19T04:00:00Z
const FRIDAY_ISO_UTC = "2025-09-19T04:00:00Z";
const boundary = new Date(FRIDAY_ISO_UTC); // JS Date
const boundaryISO = boundary.toISOString(); // For string comparisons
const client = new MongoClient(uri);
try {
await client.connect();
const coll = client.db(dbName).collection(collName);
console.log("Boundary (UTC):", boundaryISO);
// ✅ Works for both BSON Date and ISO string fields, no $convert/onError
const filter = {
$or: [
// Case 1: field is a BSON Date
{ "createdTimeStamp.dateTime": { $gte: boundary } },
// Case 2: field is an ISO string; lexicographic compare is valid for ISO-8601
{
$and: [
{ "createdTimeStamp.dateTime": { $type: "string" } },
{ "createdTimeStamp.dateTime": { $gte: boundaryISO } }
]
}
]
};
const projection = { _id: 0, applicationId: 1 };
const cursor = coll.find(filter, { projection }).batchSize(1000);
let count = 0;
for await (const doc of cursor) {
if (doc && doc.applicationId != null) {
console.log(String(doc.applicationId));
count++;
}
}
console.log("Matched:", count);
} catch (err) {
console.error("Error:", err);
} finally {
await client.close();
}
})();
backup script
// ======= CONFIG =======
const appIds = [
// Paste your IDs here, e.g.:
// "6ef60b66...", "b1a23c...", ...
];
const targetCollections = [
// List your source collections here:
];
// If some collections use a different field path for app id, map them here.
// Dotted paths are supported. Defaults to "applicationId".
const appIdPathByCollection = {
// "documents": "applicationId",
// "tasks": "meta.appId",
};
// ======= SCRIPT =======
if (!Array.isArray(appIds) || appIds.length === 0) {
throw new Error("Please populate the appIds array.");
}
targetCollections.forEach((collName) => {
const src = db.getCollection(collName);
const backupName = `backup_new_apps_${collName}`;
const backup = db.getCollection(backupName);
const appIdPath = appIdPathByCollection[collName] || "applicationId";
const query = {};
query[appIdPath] = { $in: appIds };
print(`\n[${collName}] -> [${backupName}]`);
print(`Using appId path: "${appIdPath}"`);
print(`Querying ${collName}...`);
const cursor = src.find(query).batchSize(500);
let matched = 0;
let written = 0;
const ops = [];
const BATCH = 1000;
while (cursor.hasNext()) {
const doc = cursor.next();
matched++;
// Upsert by original _id so re-runs don't duplicate
ops.push({
replaceOne: {
filter: { _id: doc._id },
replacement: doc,
upsert: true,
},
});
if (ops.length === BATCH) {
const res = backup.bulkWrite(ops, { ordered: false });
written += (res.upsertedCount || 0) + (res.modifiedCount || 0);
ops.length = 0;
print(` ...wrote ${written}/${matched}`);
}
}
if (ops.length) {
const res = backup.bulkWrite(ops, { ordered: false });
written += (res.upsertedCount || 0) + (res.modifiedCount || 0);
}
print(`Done: matched=${matched}, backed up=${written} into ${backupName}`);
});
// ======= OPTIONAL: verify counts quickly =======
// targetCollections.forEach((c) => {
// print(c, "=>", db.getCollection(c).countDocuments({}), "|",
// `backup_new_apps_${c}`, "=>", db.getCollection(`backup_new_apps_${c}`).countDocuments({}));
// });
Top comments (0)