在链式Promisified函数中创buildMongoDB文档

应用程序每15分钟运行一个进程,以下列格式创build许多输出文件:

<timestamp>-<piece-code>.txt 

由进程创build的所有文件将共享“时间戳”组件,但“片段代码”将有所不同,这意味着我有一个时间戳到多个片断的关系,我想保存在mongodb为:

 "Registry" { time: (numeric) } "Piece" { file: (string), piece: (string), registry: (reference) } 

在这个过程中,我想查找是否已经创build一个时间戳 ,以避免重复,但我的代码似乎无法做到这一点。

在此先感谢您的帮助!

 const mongoose = require('mongoose'); const Registry = require('../model/Registry'); const Piece = require('../model/Piece'); mongoose.Promise = require('bluebird'); // Set up default mongoose connection let mongoDB = 'mongodb://127.0.0.1/numbers'; mongoose.connect(mongoDB, { useMongoClient: true }); //Get the default connection let db = mongoose.connection; // Bind connection to error event db.on('error', console.error.bind(console, 'MongoDB connection error:')); // Error handler let error = (err) => { console.log("** Error: ", err); db.close(); }; // Finish routine let finish = () => { console.log("I have finished"); db.close(); }; // Create a number if it does not exist already let newRegistry = (timestamp) => { return new Promise((resolve, reject) => { Registry.count({}).then((c) => { console.log(c) }) // Does this Registry exist? Registry.findOne({ time: timestamp }) .then((reg, err) => { if (err) { reject(err); } // Create when it does not exist if (!reg) { Registry.create({ time: timestamp }).then((doc, err) => { if (err) { reject(err); } resolve(doc._id); }) .catch(error); } else { // Else, resolve resolve(reg._id); } }); }); } let newPiece = (registryId, filename, piece) => { return Piece.create({ registry: mongoose.Types.ObjectId(registryId), file: filename, piece: piece }); }; let createRegs = (files) => { return new Promise((resolve, reject) => { let promises = []; let total = files.length; for (let i=0; i<total; i++) { let fileAr = files[i].split("-"); let time = fileAr[0]; let piece = fileAr[1]; let promise = newRegistry(time) .then((regId) => { return newPiece(regId, files[i], piece); }); promises.push(promise); } Promise.all(promises) .then(() => { resolve(); }) .catch(error); }); } // Register input time and file pieces: one "time" can have many "pieces" let filenames = ["1512473256-e.txt", "1512471758-a.txt", "1512471892-a.txt", "1512471758-b.txt"]; // Must end up with 3 "Registry" and 4 "Piece" documents createRegs(filenames) .then(finish) .catch(error); 

也许值得摆脱你的数组中的重复数字? 通过做这样的事情:

 let filtered = []; numbers.forEach((num) => { // in case we don't have such entity creating it if (!filtered.includes(num)) { filtered.push(num); } // in case we have just returning resolved promise return Promise.resolve(); }); 

然后在DB中创build你的实体:

 const promises = filtered.map(n => { Number.findOne({ number: n }) .then(result => if(!result) { return Number.create({ number: n }); }).catch(err => console.log(err)); }); Promise.all(promise).then(() => /* Doing what you want to do after saving */) 

我的做法是这样的:

  1. 首先,我会创build一个字典,其中键将是时间戳,值将是一个不同的片段的数组。
  2. 一旦你有这个字典,我会对待每个时间戳列表
    • 在数据库中查找时间戳。 创build它,如果它不存在。
    • 循环遍历所有时间戳,并将其添加到数据库中。

采用这种方法可以避免并发问题。 希望能帮助到你。