【发布时间】:2021-05-28 16:53:24
【问题描述】:
我正在为 bulkWrite 操作而苦苦挣扎。我正在尝试创建大量操作来更新我的集合中的文档。对于创建的每个文档,都会使用一个插件。
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);
每个文档都需要在文档创建或更新时具有更新日期。为此,我使用了一个插件。
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;
然后在创建模型之前使用此插件。
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 };
除了 bulkWrite 函数,我还尝试将 initializeUnorderedBulkOp 与 find.upsert().updateOne() 结合使用。
在这两种情况下插件都不起作用。
非常感谢您的帮助。
提前致谢
------- 编辑 ------
我想详细说明我的用例。目标是为所有新的和更新的文档设置一个标志为真,并利用猫鼬插件来做到这一点。
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 };
原因是bulkWrite 没有发回upserted 文档。它只返回修改后的计数。我想对结果执行一个查询 MySchema.find({flag: true}) 循环,做一些魔术,然后为每个处理的项目 set the flag to false。
除了插件之外,我还尝试了setDefaultsOnInsert 和setOnInsert。可惜没有成功。
【问题讨论】: