MongooseJS-在执行bulkWrite操作之前验证所有文档

时间:2019-08-25 18:14:35

标签: javascript mongodb mongoose

我有来自外部API的以下数据(简化示例),它是足球实时比分的列表,并且该数据将动态变化。例如,minutestatus之类的字段将一直更改:

data: [
    {
        match_id: 1,
        home_team: 'Arsenal',
        away_team: 'Chelsea',
        status: 'Not started',
        minute: 0
    },
    {
        match_id: 2,
        home_team: 'Liverpool',
        away_team: 'Manchester United',
        status: 'Live',
        minute: 10
    },
    {
        match_id: 3,
        home_team: 'Arsenal',
        away_team: 'Chelsea',
        status: 'Finished',
        minute: 90
    },
];

我的猫鼬模式如下:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const FixtureSchema = new Schema(
    {
        _id: { type: mongoose.Schema.Types.ObjectId, select: false },
        match_id: { type: Number, required: true, index: true, unique: true },
        home_team: { type: String, required: true, default: 'Home Team' },
        away_team: { type: String, required: true, default: 'Away Team' },
        status: { type: String, required: true, default: 'Not started' },
        minute: { type: Number, required: true, default: 0 },
    },
    {
        versionKey: false,
    }
);

const Fixtures = mongoose.model('fixtures', FixtureSchema);
module.exports = Fixtures;

我现在要做的是每X秒运行一个函数,以保持数据库的更新。由于match_id字段是唯一的,因此我从此API提取新数据后,运行以下函数来更新数据库:

const bulkWriteOps = [];

data.forEach(item => {
    bulkWriteOps.push(
        {
            updateOne: {
                filter: { match_id: item.id },
                update: {
                    match_id: item.match_id,
                    home_team: item.home_team,
                    away_team: item.away_team,
                    status: item.status,
                    minute: item.minute
                },
                upsert: true,
            }
        }
    )
});

await Fixtures.bulkWrite(bulkWriteOps);

因此,如果存在match_id,则我用新数据更新每个唯一匹配项,否则,我将upsert更新。

这是问题所在,但是,猫鼬的bulkWrite()方法仅支持updateOne()updateMany(),但是这两个都不让我设置{ {1}}或runValidators,我需要这些,因为我不是100%相信来自API的数据是正确的,有时可能会出现诸如状态或分钟数之类的字段,因此我不得不对此加以考虑将任何数据推送到我的数据库。

我找到了一种验证单独创建的文档的方法,此外,它也自动为我setDefaultsOnInsert,例如:

setDefaultsOnInsert

但是正如我之前所说,每个文档都有一个唯一的const documents = []; data.forEach(item => { documents.push( new Fixtures({ match_id: item.match_id, home_team: item.home_team, away_team: item.away_team, status: item.status ? item.status : null, minute: item.minute ? item.minute : null }) ) }); //then you can do documents for-each .validate() or .validateSync() here before pushing to database. ,需要使用新数据进行更新,或者如果ID不存在,则需要重新插入,因此无法正常工作。


我猜整个问题都可以用TL; DR来解决:如果我有一个bulkWriteOps数组,有没有一种方法可以在运行match_id方法之前对它运行验证程序,或者采取其他解决方法为此。

PS:我知道所有这些都可以通过for循环来完成,但是这对我来说似乎是一个糟糕的解决方案,特别是因为固定装置的数量很容易超过数百个,因此对于我的情况而言不是很有效。

谢谢。

0 个答案:

没有答案