Search code examples
mongodbmongoosemongoose-schemasubdocument

Why MongoDB subdocument expiration removes parent document?


I use mongoose 5 and have a schemas like this:

user.js

const mongoose = require('mongoose');
const GeoData = require('./geodata');

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  createdAt: {
    type: Date,
    default: Date.now()
  },
  geodata: GeoData
});

UserSchema.index({ deviceToken: 1 }, { unique: true });

module.exports = UserSchema;

geodata.js

const mongoose = require('mongoose');
const c2p = require('circle-to-polygon');

const GeoDataSchema = new mongoose.Schema({
  location: {
    coordinates: [Number],
    type: {
      type: String
    }
  },
  createdAt: {
    type: Date,
    default: Date.now()
  },
  expireAt: {
    type: Date,
    default: new Date().setHours(12,0,0,0)
  }
});

GeoDataSchema.index({ location: "2dsphere", bounds: "2dsphere" });
GeoDataSchema.index({ 'expireAt': 1 }, { expireAfterSeconds: 0 });

module.exports = GeoDataSchema;

Let's say the geodata subdocument is added to the parent user document with expiration set to 12:00:00 local time by default. Unfortunately this removes parent user with subdocument geodata instead of removing geodata only as I would expect.

Is this normal behavior or am I missing something?


Solution

  • A TTL index always works on a root document, never on individual subdocuments or other parts of a document.

    According to the documentation:

    A special TTL index property supports the implementation of TTL collections. The TTL feature relies on a background thread in mongod that reads the date-typed values in the index and removes expired documents from the collection.