简体   繁体   English

Node.js Mongodb回调问题

[英]Node.js Mongodb Callback issue

My app should update if tmx is newer, if older do nothing and if doesn't exist insert the document. 如果tmx是新的,我的应用程序应该更新,如果旧的什么都不做,如果不存在,请插入文档。 If the document is inserted, it works perfectly, else it doesn't update properly or says E11000 dup key. 如果插入了文档,则可以正常工作,否则将无法正确更新或显示E11000 dup键。 trying to figure out if my callback are wrong or the logic. 试图弄清楚我的回调是错误的还是逻辑。 (I'm new to node.js+mongodb) MongoClient = require('mongodb').MongoClient, assert = require('assert'), url = 'mongodb://localhost:27017/pfc'; (我是node.js + mongodb的新手)MongoClient = require('mongodb')。MongoClient,assert = require('assert'),url ='mongodb:// localhost:27017 / pfc';

    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: The documents from the 'log.log' file have this structure: 编辑:“ log.log”文件中的文档具有以下结构:

{ vid:2848 tmx: "2015-07-18T23:56:17.000Z" } {vid:2848 tmx:“ 2015-07-18T23:56:17.000Z”}

{ vid: 2848 tmx: 2015-07-19T00:00:17.000Z } {vid:2848 tmx:2015-07-19T00:00:17.000Z}

collection.find({vid: doc.vid},function(err,item){ collection.find({vid:doc.vid},function(err,item){

if(!item) // didnt find in collection, items with vid: 2848 insert doc to collection else if(item) //found an item with vid:2848 if (item.tmx < doc.tmx)//only update if doc.tmx is newer update collection with the most recent document if(!item)//在集合中没有找到vid:2848的项目,将文档插入到集合中else if(item)//找到了具有vid:2848的项目if(item.tmx <doc.tmx)//仅在if doc.tmx是带有最新文档的更新集合

with @Aaron Dufour help I got rid of the callback problem, thanks :) but now the problem is when I have the collection already populated and go look for newest documents in log.log, it starts from the oldest document till the newest again :( 在@Aaron Dufour的帮助下,我摆脱了回调问题,谢谢:),但是现在的问题是,当我已经填充了集合并在log.log中查找最新文档时,它从最早的文档开始,直到再次出现最新的文档: (

Your upsert is vulnerable to race conditions, and run calls it many times in parallel, so that is probably the issue. 您的upsert容易受到竞争条件的影响,因此需要并行run多次调用,因此可能是问题所在。 It is not clear exactly what doc will look like, so you might need slightly more complicated logic, but here's a version that uses Mongo's upsert to make things a bit safer: 目前尚不清楚doc外观,因此您可能需要更复杂的逻辑,但是以下版本使用Mongo的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();
    });
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM