Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.92k stars 3.84k forks source link

Initialize Models on build time #14959

Open timheerwagen opened 1 week ago

timheerwagen commented 1 week ago

Prerequisites

Mongoose version

8.7.0

Node.js version

20.14.10

MongoDB version

7.x

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

11

Issue

For a backup solution i'm restoring mongodb data from a json file.

In case that a model is not yet initialized yet, I offer fallback solutions for insertMany.

export const insertMany = async ({
  name,
  data,
}: InsertManyByCollectionProps) => {
  const mongooseModel = mongoose.models[name];

// if model is initialized and already used atleast once
  if (mongooseModel) {
    await mongooseModel.insertMany(data, { ordered: false }); 

    return;
  }

  const knownModels: Record<string, mongoose.Model<any>> = {
   modelName: ExampleModel

  };

  const knownModel = knownModels[name];

// if model is known (e.g. core model)
  if (knownModel) {
    await knownModel.insertMany(data, { ordered: false }); 

    return;
  }

// fallback, if model is not initialized and not "known model" (e.g. plugin model)
  await mongoose.connection.db?.collection(name).insertMany( 
    data.map((v) => {
      const newV = { ...v };

      if (newV._id) {
        newV._id = ObjectId.createFromHexString(v._id);
      }

      if (newV.createdAt) {
        newV.createdAt = new Date(newV.createdAt);
      }

      if (newV.updatedAt) {
        newV.updatedAt = new Date(newV.updatedAt);
      }

      return newV;
    }),
    { ordered: false }
  ); 
};

Is there a way to initialize all defined models directly during creation so that the data can be parsed correctly by the schema? This is useful if the model can't be defined in a list and is not yet in use. (e.g. plugins) Otherwise I have to come up with some serialization for deeply nested ObjectId's or Dates.

vkarpov15 commented 2 days ago

I'm not sure I understand what the question is here. How are you creating your models?

timheerwagen commented 7 hours ago

One of my models:


const MongooseFileSchema = new mongoose.Schema<FileSchema>(
  {
    name: { type: String, required: true },
  },
);

MongooseFileSchema.index({
  name: "text",
});

export const FileModel =
  (mongoose.models?.[FILE_MODEL_NAME] as Model<FileSchema>) ||
  mongoose.model<FileSchema>(FILE_MODEL_NAME, MongooseFileSchema);

If this model is not yet used by FileModel.find, it is not included in mongoose.models.