I’m working on a Discord Bot but this question is about the service-end I’ve created for the bot. The scenario I’m working on is as follows, whenever a user deletes their account all of the images uploaded by said user will be removed from the GUILDS collection and placed in the DELETED_CONTENT collection. Specifically, a user’s image data will be removed from a GUILD’s image_pool array and placed in a respective DELETED_CONTENT image_pool array.
The number of images varies by user and the number of GUILDS that a user is associated also varies. image_pool data is dynamic so overwriting that would be nuanced to maintain state, whereas the rest of a GUILD’s data is static.
What I’m looking to achieve below assuming ‘jeskoston’ deletes account. I’ve added a comment to their username for clarity.
Current GUILDS (collection)
{
"_id" : ObjectId("61b3db8b965d8d06da643edd"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "philjackson",
"image_pool" : [
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbff67"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"uploaded_by_discord_username" : "jeskoston <-- WILL DELETE ACCOUNT",
"uploaded_by_id" : "619dadc90565852231712345",
"image_title" : "Jordan",
"image_url" : "/uploads/925819329911062589/1642820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null
},
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbfe88"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"uploaded_by_discord_username" : "andydiscord",
"uploaded_by_id" : "619dadc90565852231771649",
"image_title" : "Pippen",
"image_url" : "/uploads/825519329911062589/5442820844573IMG-1111.png",
"likes" : null,
"flags" : 0,
"nsfw" : null
}
],
"install_date" : "2021-12-10T22:58:19.504Z",
"discord" : {
"id" : "945819329911062589",
"owner_id" : "795864504197577734",
"system_channel_id" : "888819329911062592",
"name" : "bulls"
}
},
{
"_id" : ObjectId("61eb9a0cbcbea4139ea17123"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "georgekarl",
"image_pool" : [
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbfe90"),
"date_uploaded" : "2022-01-21T19:09:30-08:00",
"uploaded_by_discord_username" : "jeskoston <-- WILL DELETE ACCOUNT",
"uploaded_by_id" : "619dadc90565852231712345",
"image_title" : "Malone",
"image_url" : "/uploads/995519329911062100/7842820844573IMG-4000.jpg",
"likes" : null,
"flags" : 0,
"nsfw" : null
}
],
"install_date" : "2022-01-22T05:45:48.011Z",
"discord" : {
"id" : "549483811550042074",
"owner_id" : "792864524197578834",
"system_channel_id" : "849421811440042077",
"name" : "jazz"
}
}
Current DELETED_CONTENT (collection):
{
"_id" : ObjectId("88b3db8b965d8d06da643p09"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "philjackson",
"guild_uninstalled": false,
"image_pool" : [
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbfk3p"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"date_deleted" : "2022-01-25T01:07:45-08:00",
"uploaded_by_discord_username" : "andrewdiscord",
"uploaded_by_id" : "619dadc90565852231771659",
"image_title" : "Rodman",
"image_url" : "/uploads/925819329911062589/1232820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null,
"date_deleted" : "2022-01-22T19:09:25-08:00",
},
],
"install_date" : "2021-12-10T22:58:19.504Z",
"discord" : {
"id" : "945819329911062589",
"owner_id" : "795864504197577734",
"system_channel_id" : "888819329911062592",
"name" : "bulls"
}
},
{
"_id" : ObjectId("61eb9a0cbcbea4139ea17789"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "georgekarl",
"guild_uninstalled": false,
"image_pool":[{
"_id" : ObjectId("888b74edaa9c4c0f53cbff45"),
"date_uploaded" : "2022-02-23T12:07:11-08:00",
"date_deleted" : "2022-02-24T11:02:01-08:00",
"uploaded_by_discord_username" : "jakediscord",
"uploaded_by_id" : "619dadc9056585223175461f",
"image_title" : "Stockton",
"image_url" : "/uploads/925819329911062589/1232820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null,
"date_deleted" : "2022-03-22T04:09:00-08:00",
}
],
"install_date" : "2022-01-22T05:45:48.011Z",
"discord" : {
"id" : "549483811550042074",
"owner_id" : "792864524197578834",
"system_channel_id" : "849421811440042077",
"name" : "jazz"
}
}
Desired GUILDS (collection) after user jeskoston deletes their account:
{
"_id" : ObjectId("61b3db8b965d8d06da643edd"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "philjackson",
"image_pool" : [
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbfe88"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"uploaded_by_discord_username" : "andydiscord",
"uploaded_by_id" : "619dadc90565852231771649",
"image_title" : "Pippen",
"image_url" : "/uploads/825519329911062589/5442820844573IMG-1111.png",
"likes" : null,
"flags" : 0,
"nsfw" : null
}
],
"install_date" : "2021-12-10T22:58:19.504Z",
"discord" : {
"id" : "945819329911062589",
"owner_id" : "795864504197577734",
"system_channel_id" : "888819329911062592",
"name" : "bulls"
}
},
{
"_id" : ObjectId("61eb9a0cbcbea4139ea17123"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "georgekarl",
"image_pool" : [],
"install_date" : "2022-01-22T05:45:48.011Z",
"discord" : {
"id" : "549483811550042074",
"owner_id" : "792864524197578834",
"system_channel_id" : "849421811440042077",
"name" : "jazz"
}
}
Desired DELETED_CONTENT (collection) after user jeskoston deletes their account:
{
"_id" : ObjectId("88b3db8b965d8d06da643p09"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "philjackson",
"guild_uninstalled": false,
"image_pool" : [
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbff67"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"date_deleted" : "2022-01-22T19:09:25-08:00",
"uploaded_by_discord_username" : "andrewdiscord",
"uploaded_by_id" : "619dadc90565852231771659",
"image_title" : "Rodman",
"image_url" : "/uploads/925819329911062589/1232820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null,
},
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbff67"),
"date_uploaded" : "2022-01-21T19:07:25-08:00",
"date_deleted" : "2022-01-26T07:09:51-08:00",
"uploaded_by_discord_username" : "jeskoston <-- ACCT DELETED",
"uploaded_by_id" : "619dadc90565852231712345",
"image_title" : "Jordan",
"image_url" : "/uploads/925819329911062589/1642820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null
}
],
"install_date" : "2021-12-10T22:58:19.504Z",
"discord" : {
"id" : "945819329911062589",
"owner_id" : "795864504197577734",
"system_channel_id" : "888819329911062592",
"name" : "bulls"
}
},
{
"_id" : ObjectId("61eb9a0cbcbea4139ea17789"),
"preferred_locale" : "en-US",
"nsfw" : false,
"installed_by_id" : "795864504197578834",
"installed_by_username" : "georgekarl",
"guild_uninstalled": false,
"image_pool":[{
"_id" : ObjectId("888b74edaa9c4c0f53cbff45"),
"date_uploaded" : "2022-02-21T15:07:11-08:00",
"date_deleted" : "2022-03-02T04:09:00-08:00",
"uploaded_by_discord_username" : "jakediscord",
"uploaded_by_id" : "619dadc9056585223175461f",
"image_title" : "Stockton",
"image_url" : "/uploads/925819329911062589/1232820844573IMG-4148.JPG",
"likes" : null,
"flags" : 0,
"nsfw" : null,
},
{
"_id" : ObjectId("61eb74edaa9c4c0f53cbfe90"),
"date_uploaded" : "2022-01-21T19:09:30-08:00",
"date_deleted" : "2022-23-22T04:09:00-08:00",
"uploaded_by_discord_username" : "jeskoston <-- ACCT DELETED",
"uploaded_by_id" : "619dadc90565852231712345",
"image_title" : "Malone",
"image_url" : "/uploads/995519329911062100/7842820844573IMG-4000.jpg",
"likes" : null,
"flags" : 0,
"nsfw" : null
}
],
"install_date" : "2022-01-22T05:45:48.011Z",
"discord" : {
"id" : "549483811550042074",
"owner_id" : "792864524197578834",
"system_channel_id" : "849421811440042077",
"name" : "jazz"
}
}
My strategy thus far has been to #1 pull a user’s images from the GUILDS collection but before doing that #2 copy data to push to the DELETED_CONTENT collection.
I have #1 finished
For #2 I have a query that collects a user’s image data and adds a date_deleted timestamp to each image. I also include other GUILD data in query. I only return guild entries where a user has images posted.
('GUILDS').aggregate([
{
$project:
{
discord:1,
install_date:1,
installed_by_id:1,
installed_by_username:1,
preferred_locale:1,
nsfw:1,
guild_deleted:1,
user_images:
{
$filter:
{
input:"$image_pool",
as: "image",
cond:{ $eq: ["$$image.uploaded_by_id",'619dadc90565852231771659'] }
}
}
}
},
{
$addFields: {
guild_deleted:false,
"user_images":{
$map:{
input: "$user_images",
as:"image",
in:{
_id:"$$image._id",
date_deleted: "$$NOW",
date_uploaded:"$$image.date_uploaded",
uploaded_by_discord_username:"$$image.uploaded_by_discord_username",
uploaded_by_id:"$$image.uploaded_by_id",
image_title:"$$image.image_title",
image_url:"$$image.image_url",
likes:"$$image.likes",
flags:"$$image.flags",
nsfw:"$$image.nsfw"
}
}
}
}
},
{
$match:{ 'user_images.0':{ $exists: true } }
}
])
I retrieve user data based on an images ‘uploaded_by_id’ value. I include static guild info in the event I have to upsert the whole document, user_images are a user’s images from a GUILD’s respective image_pool(s).
I want to be able to move this data without looping calls to the database. I’ve tried to use bulkWrite but have had no luck, I cannot find a concrete example that has a use-case for a dynamic number of entries. I’ve attempted to create a dynamic string for bulkWrite with no luck. I’ve also attempted to use $merge but I’m having trouble with the pipeline operators under whenMatched field.
Maybe my entire approach is off? I will spare my other attempts since this has gotten long. I’m not sure if anyone can help, but any attempt would be appreciated.