Reputation: 21
I'm struggling with the bulkWrite operation. I'm trying to create a bulk of operations that upsert documents in my collection. For each document created a plugin is utilised.
const documents = [];
const count = 1000;
for (let i = 0; i < count; i++) {
documents.push(
{
updateOne:
{
filter: { itemId: i },
update: { $set: { name: i } },
upsert: true
}
}
);
}
await MyModel.bulkWrite(documents);
Each document needs to have an updated at date for when the document as either created or updated. For that I use a plugin.
const plugin = function updateAtPlugin(schema: any, options: any) {
schema.add({ updatedAt: Date });
schema.post('updateOne', function (next: any) {
this.updatedAt = new Date;
next();
});
if (options && options.index) {
schema.path('updatedAt').index(options.index);
}
};
export default plugin;
This plugin is then used before the model is created.
import { Schema, model } from 'mongoose';
import updatedAtPlugin from './update-plugin';
const MySchema: Schema = new Schema({
itemId: {
type: String,
required: true,
index: true
},
attributes: Object
});
MySchema.plugin(updatedAtPlugin);
const MyModel: any = model('my-name', MySchema);
export { MyModel };
In addition to the bulkWrite function I've also tried initializeUnorderedBulkOp in combination with find.upsert().updateOne().
In both cases the plugin is not working.
I would really appreciate some help.
Thanks in advance
------- EDIT ------
I'd like to elaborate on my use case. The goal is to have a flag set as true for all new and updated documents and utilising a mongoose plugin to do so.
const plugin = function updated(schema: any, options: any) {
schema.post('updateOne', function (next: any) {
this.flag = true
next();
});
if (options && options.index) {
schema.path('flag').index(options.index);
}
};
export default plugin;
import { Schema, model } from 'mongoose';
import updated from './updated-plugin';
const MySchema: Schema = new Schema({
itemId: {
type: String,
required: true,
index: true
},
attributes: Object,
flag: {
type: Boolean,
default: true
}
});
MySchema.plugin(updated);
const MyModel: any = model('my-name', MySchema);
export { MyModel };
The reason why is because the bulkWrite doesn't send back the upserted
documents. It only returns a modified count. I'd like to execute a query MySchema.find({flag: true})
loop through the result, do some magic and then set the flag to false
for each processed item.
In addition to a plugin I've also tried setDefaultsOnInsert
and setOnInsert
. Unfortunately without success.
Upvotes: 1
Views: 411
Reputation: 1440
You don't need a custom plugin, mongoose has that built in.
Adding { timestamps: true }
as a second argument to your schema adds createdAt
and updatedAt
automatically to all your documents.
const MySchema: Schema = new Schema({
itemId: {
type: String,
required: true,
index: true
},
attributes: Object
}, { timestamps: true });
Upvotes: 1