2015-08-09 3 views
0

Мое приложение должно обновить, если tmx новее, если более старые ничего не делают, а если нет, вставьте документ. Если документ вставлен, он отлично работает, иначе он не обновляется должным образом или не говорит ключ E11000 dup. пытается выяснить, ошибочен ли мой обратный вызов или логика. (Я новичок в node.js + mongodb) MongoClient = require ('mongodb'). MongoClient, assert = require ('assert'), url = 'mongodb: // localhost: 27017/pfc';Node.js Mongodb Callback issue

MongoClient.connect(url, function (err, db) { 
     run(db); 
    }); 


    function run(db) { 
     fs.readFile('log.log', 'utf8', function (err, source) { 
      if (err) throw err; 
      var dataFile = JSON.parse(source); 
      dataFile.forEach(function (item) { 
       upsert(db, item, function (err, result) { 
        if (err) console.dir(err); 

       }); 
      }); 
     }) 
    } 

    function upsert(db, doc, callback) { 

    db.collection('flags').findOne({vid: doc.vid}, function (err, item, result) { 

     if (item.vid != null) { 
      if (!(item.tmx instanceof Date)) { 
       item.tmx = new Date(item.tmx) 
      } 
      if(!(doc.tmx instanceof Date)){ 
       doc.tmx = new Date(doc.tmx) 
      } 

      if (item.tmx < doc.tmx) { 
       console.dir("Date validation") 
       db.collection('flags').updateOne({vid: item.vid}, { 
         $set: { 
          "tmx": doc.tmx 
         } 
        },{upsert:true}, function (err, result) { 
         callback(err, result); 

        } 
       ) 

       callback(err, result); 
      } 
      else{ 
       console.dir("older") 
       callback(err, result); 
      } 
     } 
     else { 
      db.collection('flags').insertOne(doc, function(err, result) { 
       callback(err, result); 
      }); 
     } 
    })} 

Edit: документы из файла 'log.log' имеют такую ​​структуру:

{ VID: 2848 TMX: "2015-07-18T23: 56: 17.000Z" }

{ VID: 2848 TMX: 2015-07-19T00: 00: 17.000Z }

collection.find ({VID: doc.vid}, функция (е р-р, п) {

если (пункт) // не нашли в коллекции предметов с VID: 2848 вставка док для сбора еще если (пункт) // найден элемент с VID: 2848 если (пункт .tmx < doc.tmx) // только обновление, если doc.tmx новее коллекции обновления с последним документом

с @Aaron Dufour помощью я избавился от проблемы обратного вызова, спасибо :) но теперь проблема когда у меня уже собрана коллекция и ищите новейшие документы в log.log, она начинается с самого старого документа до самого нового :(

+1

Вашей upsert логика уязвима к условиям гонки, что может вызвать проблемы. Вы пробовали встроенный upsert Монго? –

+0

Не могу увидеть, как его использовать, когда мне нужно сравнить даты с обновлением –

+0

, так как если элемент не существует, я получаю свойство item.tmx null error, поэтому мне нужно подтвердить, что элемент существует, поэтому я могу сравнить дата из файла с датой с mongodb –

ответ

1

Ваш upsert уязвим для условий гонки, а run называет это много раз параллельно, так что это, вероятно, проблема. Не ясно, что именно doc будет выглядеть, так что вам, возможно, потребуется немного более сложная логика, но вот версия, которая использует upsert Монго, чтобы сделать вещи немного безопаснее:

function upsert(db, doc, callback) { 
    db.collection('flags').update({vid: doc.vid}, {$set: doc}, {upsert: true}, function(err) { 
    db.collection('flags').update({vid: doc.vid, tmx: {$lt: doc.tmx}}, {$set: tmx: doc.tmx}, function(err) { 
     callback(); 
    }); 
    }); 
} 
+0

m8 ты гений, спас свою жизнь: D –

+0

нашел небольшую ошибку, Например, самая старая запись с 07/08/2015 00:00:17 и самая новая с сегодняшнего дня. Если я запустил приложение еще раз, он будет обновляться до самого старого и идти до нового, то, как я пытался, не работал. :( Как избежать этого? –

+1

@TelmoIvo Я не понимаю проблемы, с которой вы столкнулись. Возможно, отредактируйте ее в вопросе, чтобы у вас было больше возможностей объяснить это? –