javascript - Pg-promise 性能提升 : Multiple inserts with multiple update parameters

标签 javascript node.js performance postgresql-9.5 pg-promise

我正在按照建议实现 Vitaly 的 pg-promise 性能模式 herethere .

这是我的代码:

for (var i=0;i<chunkedData.length;i++){

    var insertData = chunkedData[i].map(function (d) {
        return {
            application_id: d.application_id,
            country_id: d.country_id,
            collection_id: collectionId
        };
    });

    // Would need to make a loop here, and thus turning the result into an array
    var updateData = {
        application_id: chunkedData[i][j].application_id,
        country_id: chunkedData[i][j].country_id,
        collection_id: collectionId
    };

      var query = h.insert(insertData, cs) +
          " ON CONFLICT ON CONSTRAINT application_average_ranking_application_id_country_id_colle_key DO UPDATE SET " +
          h.sets(updateData, cs);

    db.none(query)
        .then(data => {
            console.log('success');
        })
        .catch(error=> {
            console.log('insert error : ' + error);
        });
}

我的问题是 insertData 是一个对象数组,而库的 insert helper使用该数组构建插入请求,如 pg-promise API 中指定.而 updateData 必须是一个简单的对象。

我希望在 :

ON CONFLICT ON CONSTRAINT constraintName DO UPDATE 

被触发,更新值与“insertData”数组中的相应对象匹配。

我该如何解决这个问题?

我试图将所有内容放入循环中,但它会疯狂地泄漏内存,好吧,我失去了该模式的好处...

编辑:

我希望我的查询等同于:

 var inserts = data.map(entry => {
    return t.none(" INSERT INTO application_average_ranking (application_id,country_id,collection_id) VALUES ($1,$2,$3)" +
                 " ON CONFLICT ON CONSTRAINT application_average_ranking_application_id_country_id_colle_key" +
                 " DO UPDATE SET country_id=$2,collection_id=$3",
                 [entry.application_id,entry.country_id,collectionId]
    );
});

在这种情况下,当调用 Update 时,参数指的是最初建议插入的值。

最佳答案

您的任务需要一个静态 SQL 来实现这种逻辑,方法是使用 EXCLUDED 作为表引用,并由于冲突而排除行:

var sqlConflict = " ON CONFLICT ON CONSTRAINT" +
    " application_average_ranking_application_id_country_id_colle_key" +
    " DO UPDATE SET application_id = excluded.application_id" +
    " country_id = excluded.country_id, collection_id = excluded.collection_id";

var insertData = chunkedData.map(function (d) {
    return {
        application_id: d.application_id,
        country_id: d.country_id,
        collection_id: collectionId
    };
});

var query = h.insert(insertData, cs) + sqlConflict;

db.none(query)
    .then(data => {
        console.log('success');
    })
    .catch(error=> {
        console.log('insert error : ' + error);
    });

更新

如果您的排除字段静态列表太长并且您想简化它,您始终可以依靠 helpers 的灵 active 。方法:

// or pull them from an object using `Object.keys(obj)`:
var cols = ['application_id', 'country_id', 'collection_id'];

var sets = pgp.helpers.sets({}, cols.map(c=> ({
    name: c, mod: '^', def: 'excluded.' + pgp.as.name(c)
})));

console.log(sets);
//=> "application_id"=excluded."application_id","country_id"=excluded."country_id",
//   "collection_id"=excluded."collection_id"

// or its simple JavaScript equivalent:
var sets = cols.map(c=> {
    var name = pgp.as.name(c);
    return name + '=excluded.' + name;
}).join();

更新

对于库的 7.3.0 版及更高版本,您应该使用方法 assignColumns生成所有排除的集合,如下所示:

cs.assignColumns({from: 'EXCLUDED'})
//=> "application_id"=EXCLUDED."application_id","country_id"=EXCLUDED."country_id","collection_id"=EXCLUDED."collection_id"

或者,如果你想跳过 application_id,那么你可以这样做:

cs.assignColumns({from: 'EXCLUDED', skip: 'application_id'})
//=> "country_id"=EXCLUDED."country_id","collection_id"=EXCLUDED."collection_id"

参见 ColumnSet.assignColumns

关于javascript - Pg-promise 性能提升 : Multiple inserts with multiple update parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37295919/

相关文章:

javascript - 通过 AngularJS 中的弹出窗口传递模型值

javascript - 将非 NODE_ENV 变量从 gulpfile 传递到其他 js 文件

node.js - 如何在 View 中一致地访问用户是否经过身份验证

r - 聚合行及时关闭

performance - 每个存储桶的最大沙发床 View 数

javascript - 为什么 webpack 4 包含单个命名导入的整个文件?

javascript - Eslint:仅在插件规则上使用

javascript - React onChange 事件不会触发

arrays - 使用 MEAN 堆栈存储来自 angularjs 表单的数组数据

java - 有哪些 Java 实用程序可用于对机器的 CPU、内存、磁盘和网络 I/O 性能进行基准测试?