通过Node.js写脚本文件到数据库中批量运行

331 阅读2分钟

业务需求

将数据库(mongo)中的某个字段所有数据替换为其他表中的某个字段的数据,通过node写替换数据的脚本,脚本最后生成的数据的主要形式为数据库操作的命令语句,可在数据库中批量执行

步骤

  • 准备数据

    从数据库中导出数据为json格式,其中涉及到的json文件如下:

cd.json

[{
  "_id": {
    "$oid": "1"
  },
  "schoolId": "BEEDB73F",
  "state": "REVISING",
  "lastUpdaterOid": {
    "$oid": "60e512a5eb2e1011d27d839f"
  },
  "lastUpdateTime": {
    "$date": "2021-09-15T06:42:29.880Z"
  }
},{
  "_id": {
    "$oid": "2"
  },
  "schoolId": "BEEDB73F",
  "state": "REVISING",
  "lastUpdaterOid": {
    "$oid": "60e512a5eb2e1011d27d839f"
  },
  "lastUpdateTime": {
    "$date": "2021-09-15T06:42:41.453Z"
  }
}]

user.json

[{
  "_id": {
    "$oid": "1"
  },
  "schoolId": "EBF606BA",
  "teacherOid": {
    "$oid": "6203803c9f0cf06f2cca8f4b"
  },
  "teachUserId": "5090AC8D"
},{
  "_id": {
    "$oid": "2"
  },
  "schoolId": "EBF606BA",
  "teacherOid": {
    "$oid": "620c97fc8f30cf6d7f60c28c"
  },
  "teachUserId": "2E250C89"
}]

rr.json

{
  "_id": {
    "$oid": "1"
  },
  "schoolId": "EBF606BA",
  "entityType": "CLAZZ_DESIGN",
  "entityOid": {
    "$oid": "620c76920311a441b2bae7df"
  },
  "operatorTeachUserId": "5090AC8D",
  "operateTime": {
    "$date": "2022-02-16T09:44:17.698Z"
  }
},{
  "_id": {
    "$oid": "2"
  },
  "schoolId": "EBF606BA",
  "entityType": "CLAZZ_DESIGN",
  "entityOid": {
    "$oid": "620c78360311a441b2bae7e7"
  },
  "operatorTeachUserId": "5090AC8D",
  "operateTime": {
    "$date": "2022-02-16T09:44:17.699Z"
  }
}]
  • 需要的数据

    业务逻辑: 后端给了一个数据库的命令,要求要相应的数据塞到相应的地方,例如:

db.courseDesigns.update({schoolId: 'EBF606BA-A256-783B-13E1-2F667844C17A', _id: ObjectId('620cc31b98f37d0bf90738be')},
    {
        $set: {
        'refLastOp.op': 'UPDATE',
        'refLastOp.opTime': ISODate("2022-03-15T06:31:04.038Z"),
        'refLastOp.operatorId': '5090AC8D',
    }
})

其中schoolId、_id、以及$set中的内容都需要写脚本将json中的数据塞进去。

  • 代码

根据业务需求写逻辑代码,比如我的业务逻辑:

当rr.json中的数据schoolId和cd.json中的scholId相等且rr.json中的entityOid和cd.json中_id相等时,取rr.json中最新的时间为refLastOp.optime,当users.json中的teacherOid和cd.json中的lastUpdaterOid相同的时候,取teachUserId为refLastOp.operatorId

附上代码action.js:

const majorDesigns = require('./cd.json');
const revisionCourses = require('./rr.json');
const users = require('./users.json');

function getData(dataName, dbName,  type) {
    let courses = []
    // 处理课程

    dataName.forEach((courseDesign) => {
        let c = {
            _id: courseDesign._id.$oid,
            schoolId: courseDesign.schoolId,
            refLastOp: {
                op: "UPDATE", // update
                opTime: "",
                operatorId: "",
            }
        }


        // 处理 opTime
        let r = revisionCourses.filter(revisionCourse => (revisionCourse.schoolId === courseDesign.schoolId && courseDesign._id.$oid === revisionCourse.entityOid.$oid));
        r.sort((a, b) =>  new Date(b.operateTime.$date) - new Date(a.operateTime.$date)); // 倒序排序
        c.refLastOp.opTime = r[0].operateTime.$date; // 如果有很多条 schoolId 相同的则取最新的时间

        // 处理 operatorId
        let o = users.filter(mqpAdmin => mqpAdmin.teacherOid.$oid === courseDesign.lastUpdaterOid.$oid);
        if(o.length === 0) {// courseDesigns中的lastUpdaterOid与mqpAdmin中对应的teacherOid可能不存在,设置为courseDesigns的lastUpdaterOid
            c.refLastOp.operatorId = '';
        } else {
            c.refLastOp.operatorId = o[0].teachUserId;
        }
            
        courses.push(c);
    })

    // 打印数据-后面使用命令写入文件中
    courses.forEach(course => {
        console.log(`
            db.${dbName}.update({schoolId: '${course.schoolId}', _id: ObjectId('${course._id}')},
            {$set: {
                'refLastOp.opTime': ISODate("${course.refLastOp.opTime}"),
                'refLastOp.operatorId': '${course.refLastOp.operatorId}',
                }
            })
        `)
    })
}

// 调用函数
getData(majorDesigns, 'majorDesigns', 'MAJOR_DESIGN');


// 刷数据命令-在命令行执行-将console.log的内容打印到c.txt文件中
// node .\action.js > c.txt