首页 > 解决方案 > 创建 Mongoose BulkWrite 插件

问题描述

我正在为 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为每个处理的项目。

除了插件之外,我还尝试过setDefaultsOnInsertsetOnInsert. 不幸的是没有成功。

标签: node.jsmongodbmongoose

解决方案


你不需要自定义插件,猫鼬内置了。

{ timestamps: true }作为第二个参数添加到您的架构中会自动添加createdAt到您updatedAt的所有文档中。

const MySchema: Schema = new Schema({
    itemId: {
        type: String,
        required: true,
        index: true
    },
    attributes: Object
}, { timestamps: true });

推荐阅读