Search code examples
node.jsmongodbmongoosemongoose-schema

Mongoose when schema.index expires delete all subdocuments


Main question: How can I delete subdocuments when a document expires? (with mongoose index() method)

Details:

When a user registered the backend creates for them workspaces and projects.

{
    *user fields*
    "workspaces": [
        {
            "owner": "5f0dc0a6fefaaf1040796f21",
            "projects": [
                {
                    "owner": "5f0dc0a6fefaaf1040796f21",
                    "workspace": "5f0dc0a6fefaaf1040796f22",
                    "title": "EXAMPLE PROJECT",
                    "id": "5f0dc0a6fefaaf1040796f24"
                }
            ],
            "title": "Personal",
            "id": "5f0dc0a6fefaaf1040796f22"
        },
        {
            "owner": "5f0dc0a6fefaaf1040796f21",
            "projects": [],
            "title": "Shared with me",
            "id": "5f0dc0a6fefaaf1040796f23"
        }
    ],
    "id": "5f0dc0a6fefaaf1040796f21"
}

Here is one part of the userschema:

const UserSchema = new Schema({
  workspaces : [{ type: Schema.Types.ObjectId, ref: 'Workspace' }],
  confirmed: {
    type: Boolean,
    default: false
  },
  confirmToken: {
    type: String,
    default: ''
  },
  confirmTokenExpires: {
    type: Date,
    default: () => new Date(+new Date() + 60 * 60 * 1000) //60 minutes
  }, *more fields
});

The user have 1 hour to confirm their email address, after this the user should be deleted with the subdocuments. The user deleted now, but the subdocuments dont.

UserSchema.index(
  { 'confirmTokenExpires': 1 },
  {
      expireAfterSeconds: 0,
      partialFilterExpression: { 'confirmed': false }
  }
)

I tried to find a solution, but here i am, hoping :) Thanks in advance!


Solution

  • MongoDB does not support foreign keys and doesn't have something similar to cascade deletes. You have at least three options:

    1. Create workspaces only after the user is confirmed.
    2. Embed workspaces within users directly. Hard to tell whether this is viable without more details about your project.
    3. Delete "expired" users manually without the expiring index in repeating background job.