【问题标题】:MongoDB BulkWrite update operation $set not workingMongoDB BulkWrite 更新操作 $set 不工作
【发布时间】:2021-01-01 13:02:29
【问题描述】:

我正在通过对每个产品执行 bulkWrite updateOne 操作来遍历产品(变量记录)。

更新记录后,我可以看到预订数组被添加到文档中,totalQuantity 更新为预期值(例如:如果 totalQuantity 为 2000,loadingTotal 为 600,则更新后的 totalQuantity 为 1400)

正如您在 $set: { currentQuantity: "$totalQuantity" } 行中看到的,我正在尝试将 totalQuantity(1400) 分配给 currentQuantity。但这不起作用。

for (const el of records) {
        promiseArray.push(
          Stock.bulkWrite(
            [
              {
                updateOne: {
                  filter: {
                    index: el.index,
                    product: el.product,
                    batchNo: el.batchNo,
                    agency,
                    totalQuantity: { $gte: el.loadingTotal },
                  },
                  update: {
                    $push: {
                      reservations: {
                        loadingSheetId: sheetAfterSave._id,
                        reservedCaseQuantity: el.loadingCaseCount,
                        reservedUnitQuantity: el.loadingUnitCount,
                        reservedTotalQuantity: el.loadingTotal,
                      },
                    },
                    $inc: { totalQuantity: -el.loadingTotal },
                    $set: { currentQuantity: "$totalQuantity" } // Issue
                  },
                },
              },
            ],
            { session: session }
          )
        );
      }

  const result = await Promise.all(promiseArray);
  console.log('******** Result Promise ********', result);

知道如何解决这个问题吗??

错误信息

[distribution] CastError: Cast to Number failed for value "$totalQuantity" at path "currentQuantity"
[distribution]     at SchemaNumber.cast (/app/node_modules/mongoose/lib/schema/number.js:384:11)
[distribution]     at SchemaNumber.SchemaType.applySetters (/app/node_modules/mongoose/lib/schematype.js:1031:12)
[distribution]     at SchemaNumber.SchemaType._castForQuery (/app/node_modules/mongoose/lib/schematype.js:1459:15)
[distribution]     at SchemaNumber.castForQuery (/app/node_modules/mongoose/lib/schema/number.js:436:14)
[distribution]     at SchemaNumber.SchemaType.castForQueryWrapper (/app/node_modules/mongoose/lib/schematype.js:1428:15)
[distribution]     at castUpdateVal (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:520:19)
[distribution]     at walkUpdatePath (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:347:22)
[distribution]     at castUpdate (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:94:7)
[distribution]     at /app/node_modules/mongoose/lib/helpers/model/castBulkWrite.js:70:37
[distribution]     at /app/node_modules/mongoose/lib/model.js:3502:35
[distribution]     at each (/app/node_modules/mongoose/lib/helpers/each.js:11:5)
[distribution]     at /app/node_modules/mongoose/lib/model.js:3502:5
[distribution]     at /app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:5
[distribution]     at new Promise (<anonymous>)
[distribution]     at promiseOrCallback (/app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:30:10)
[distribution]     at Function.Model.bulkWrite (/app/node_modules/mongoose/lib/model.js:3500:10) {
[distribution]   stringValue: '"$totalQuantity"',
[distribution]   messageFormat: undefined,
[distribution]   kind: 'Number',
[distribution]   value: '$totalQuantity',
[distribution]   path: 'currentQuantity',
[distribution]   reason: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
[distribution]
[distribution]     assert.ok(!isNaN(val))
[distribution]
[distribution]       at castNumber (/app/node_modules/mongoose/lib/cast/number.js:28:10)
[distribution]       at SchemaNumber.cast (/app/node_modules/mongoose/lib/schema/number.js:382:12)
[distribution]       at SchemaNumber.SchemaType.applySetters (/app/node_modules/mongoose/lib/schematype.js:1031:12)
[distribution]       at SchemaNumber.SchemaType._castForQuery (/app/node_modules/mongoose/lib/schematype.js:1459:15)
[distribution]       at SchemaNumber.castForQuery (/app/node_modules/mongoose/lib/schema/number.js:436:14)
[distribution]       at SchemaNumber.SchemaType.castForQueryWrapper (/app/node_modules/mongoose/lib/schematype.js:1428:15)
[distribution]       at castUpdateVal (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:520:19)
[distribution]       at walkUpdatePath (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:347:22)
[distribution]       at castUpdate (/app/node_modules/mongoose/lib/helpers/query/castUpdate.js:94:7)
[distribution]       at /app/node_modules/mongoose/lib/helpers/model/castBulkWrite.js:70:37
[distribution]       at /app/node_modules/mongoose/lib/model.js:3502:35
[distribution]       at each (/app/node_modules/mongoose/lib/helpers/each.js:11:5)
[distribution]       at /app/node_modules/mongoose/lib/model.js:3502:5
[distribution]       at /app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:5
[distribution]       at new Promise (<anonymous>)
[distribution]       at promiseOrCallback (/app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:30:10) {
[distribution]     generatedMessage: true,
[distribution]     code: 'ERR_ASSERTION',
[distribution]     actual: false,
[distribution]     expected: true,
[distribution]     operator: '=='
[distribution]   }
[distribution] }

没有运气。

以下示例来自 mongo 官方文档

{ "_id" : 1, "name" : "A", "hours" : 80, "resources" : 7 },
{ "_id" : 2, "name" : "B", "hours" : 40, "resources" : 4 }

db.planning.aggregate(
   [
     { $project: { name: 1, workdays: { $divide: [ "$hours", 8 ] } } }
   ]
)

{ "_id" : 1, "name" : "A", "workdays" : 10 }
{ "_id" : 2, "name" : "B", "workdays" : 5 }

使用 $hours 表示 2 个文档中的动态值。但在我的情况下,“$totalQuantity”不起作用

https://docs.mongodb.com/manual/reference/operator/aggregation/divide/

【问题讨论】:

  • 怎么不工作了?您收到错误消息吗?
  • @LajosArpad 我收到上述错误。 (编辑了问题)。 totalQuantity 和 currentQuantity 在 mongoose Schema 中具有 Number 类型。我不知道为什么这是一个问题:(

标签: mongodb mongoose


【解决方案1】:

问题是您试图在此行中存储“$totalQuantity”的文本而不是数值:

$set: { currentQuantity: "$totalQuantity" }

取而代之的是一个硬编码的数值

$set: { currentQuantity: 5 }

将值设置为 5。现在,您需要找出动态值是什么。如果您有一个以数字为值的 $totalQuantity 变量,那么您可以执行以下操作:

$set: { currentQuantity: $totalQuantity }

如果没有,那么您将需要弄清楚如何访问您需要的价值并使用这些知识来访问它。

【讨论】:

  • 这个 $set 运气不好:{ currentQuantity: $totalQuantity }。检查更新的问题
  • @ShankaSomasiri 是 $set: {currentQuantity: el.loadingTotal} 工作得更好吗?
  • 是的 $set: {currentQuantity: el.loadingTotal} 工作正常。但不是 $set: { currentQuantity: $totalQuantity }。我需要在 $inc: { totalQuantity: -el.loadingTotal } 之后设置最终值。如果初始 totalQuantity 为 2000,则 $inc 之后 totalQuantity 将为 2000 - 400。(400 为 el.loadingTotal)
  • 实际上 Lajos 我需要 totalQuantity 的最新值,而不是 el.loadingTotal,因为我需要 totalQuantity 的最新值用于未来的计算。所以我需要进一步的帮助。无论如何,感谢您到目前为止的帮助
  • @ShankaSomasiri 我明白了。我对你的数据库了解不多。您如何确定哪个是最新值?
【解决方案2】:

Prasad_Saya

嗨@Shanka_Somasiri,我不确定你在尝试什么。例如,以下是使用聚合管道进行更新的方法。

我有一个输入文档:

{
   _id: 1,
   reservations: [ ]
}

这是我要推送到预订数组中的文档。

var docToUpdate = { loadingShetId: 12, reservedCaseQty: 200 }

更新查询:

db.test.updateOne(
  { _id: 1 },
  [
    {
         $set: {
             reservations: {
                 $concatArrays: [ "$reservations", [ docToUpdate ] ]
             }
         }
    }
  ]
)

更新的文档:

{
        "_id" : 1,
        "reservations" : [
                {
                        "loadingShetId" : 12,
                        "reservedCaseQty" : 200
                }
        ]
}

剩余字段更新:

$inc: { totalQuantity: -el.loadingTotal }
$set: { currentQuantity: "$totalQuantity" }

可编码如下:

totalQuantity: { $add: [ "$totalQuantity", -el.loadingTotal ] }
currentQuantity: "$totalQuantity"

所以,更新查询会变成:

db.test.updateOne(
  { _id: 1 },
  [
    {
         $set: {
             reservations: {
                 $concatArrays: [ "$reservations", [ docToUpdate ] ]
             },
             totalQuantity: { $add: [ "$totalQuantity", -el.loadingTotal ] },
             currentQuantity: "$totalQuantity"
         }
    }
  ]
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 2017-03-19
    • 2015-03-23
    相关资源
    最近更新 更多