首页 > 解决方案 > 在 JavaScript 中使用对象数组

问题描述

我有以下 JavaScript,我想将相关日期添加到 Date 对象,然后保存。我正在尝试如下

let orderIdDateCorrectionDict = [ 
    { "orderId": "2020053100", "dayCorrection": -146 }, 
    { "orderId": "2020053109", "dayCorrection": -146 }, 
    { "orderId": "2020053100", "dayCorrection": -146 }, 
];

migrateUp(db.Orders);
var index = 0;

function migrateUp(targetCollection) {

    targetCollection.find({
        OrderId: { $in: orderIdDateCorrectionDict.map(i => i.orderId) }
    }).forEach(
        function (order) {

            order.TransDate.DateTime = order.TransDate.DateTime.addDays(orderIdDateCorrectionDict[index++].dayCorrection);
            order.TransDate.Ticks = NumberLong((order.TransDate.DateTime.getTime() * 10000) + 621355968000000000);

            targetCollection.save(order);
        }
    );
};

Date.prototype.addDays = function (days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

它给了我错误

{“消息”:“无法读取未定义的属性'dayCorrection'”,“堆栈”:“脚本:9478:126”+“脚本:14:70”+“脚本:14:70”+“脚本:9475:8 " + "脚本:9460:1" }

如何使用正确的 day int 值更新相关记录?

标签: javascriptmongodb

解决方案


The error is evidence that there are duplicate order ids in the data. As a result, the find produces more orders than there are elements in orderIdDateCorrectionDict, and the index gets incremented beyond the end of that array, producing an undefined value (and thus "cannot read property ... of undefined")

As a debug step, confirm that you get exactly N orders when querying N ids. If you don't, then you have non-unique ids, and the fix should be made elsewhere, wherever those duplicates are created.

To guard the OP code against this problem, independent how the ids are setup, don't use a parallel index counter. Instead, lookup the correction by orderId, like this...

function orderCorrectionForId(orderId) {
  return orderIdDateCorrectionDict.find(oc => oc.orderId === orderId)
}

// no need for the index variable
// in the forEach loop...

function (order) {
  let correction = orderCorrectionForId(order.OrderId)
  if (correction) {
    order.TransDate.DateTime = order.TransDate.DateTime.addDays(correction.dayCorrection);
    // and so on...
  }

But start with just logging the order in that forEach function, so you can get to the root problem, which is a query result that you don't expect.


推荐阅读