如何在订购mongodb时bulkWrite减少产品数量?

ttp71kqs  于 2023-02-15  发布在  Go
关注(0)|答案(1)|浏览(166)

我在mongodb中有一个表"products":

{
"_id": "62ab02ebd3e608133c947798",
"status": true,
"name": "Meat",
"type": "62918ab4cab3b0249cbd2de3",
"price": 34400,
"inventory": [
  {
    "_id": "62af007abb78a63a44e88561",
    "locator": "62933b3fe744ac34445c4fc0",
    "imports": [
      {
        "quantity": 150,
        "_id": "62aefddcd5b52c1da07521f2",
        "date_manufacture": "2022-03-01T10:43:11.842Z",
        "date_expiration": "2023-05-20T10:43:20.431Z"
      },
      {
        "quantity": 200,
        "_id": "62af007abb78a63a44e88563",
        "date_manufacture": "2022-04-01T10:45:01.711Z",
        "date_expiration": "2023-05-11T10:45:06.882Z"
      }
    ]
  },
  {
    "_id": "62b3c2545a78fb4414dd718f",
    "locator": "62933e07c224b41fc48a1182",
    "imports": [
      {
        "quantity": 120,
        "_id": "62b3c2545a78fb4414dd7190",
        "date_manufacture": "2022-03-01T01:30:07.053Z",
        "date_expiration": "2023-05-01T10:43:20.431Z"
      }
    ]
  }
],
}

我想在inventoryimports中按id减少一个locator中的数量(批量写入)。我可以按date_expiration排序减少数量吗?
例如:当客户订购数量为300、货位为62933b3fe744ac34445c4fc0的产品时,我希望进行如下产品更新:

{
...
"name": "Meat",
"price": 34400,
"inventory": [
  {
    "_id": "62af007abb78a63a44e88561",
    "locator": "62933b3fe744ac34445c4fc0",
    "imports": [
      {
        "quantity": 50,
        "_id": "62aefddcd5b52c1da07521f2",
        "date_manufacture": "2022-03-01T10:43:11.842Z",
        "date_expiration": "2023-05-20T10:43:20.431Z"
      }
    ]
  },
  {
    "_id": "62b3c2545a78fb4414dd718f",
    "locator": "62933e07c224b41fc48a1182",
    "imports": [
      {
        "quantity": 120,
        "_id": "62b3c2545a78fb4414dd7190",
        "date_manufacture": "2022-03-01T01:30:07.053Z",
        "date_expiration": "2023-05-01T10:43:20.431Z"
      }
    ]
  }
],
}

太感谢你了!

arknldoa

arknldoa1#

您应该将模式重构为嵌套数组,因为它被认为是反模式,会给查询带来不必要的复杂性。
选项之一:

db={
  "products": [
    {
      "_id": "62ab02ebd3e608133c947798",
      "status": true,
      "name": "Meat",
      "type": "62918ab4cab3b0249cbd2de3",
      "price": 34400,
      "inventory": [
        "62af007abb78a63a44e88561",
        "62b3c2545a78fb4414dd718f"
      ]
    }
  ],
  "inventory": [
    {
      "_id": "62af007abb78a63a44e88561",
      "locator": "62933b3fe744ac34445c4fc0",
      "imports": [
        {
          "quantity": 150,
          "_id": "62aefddcd5b52c1da07521f2",
          "date_manufacture": ISODate("2022-03-01T10:43:11.842Z"),
          "date_expiration": ISODate("2023-05-20T10:43:20.431Z")
        },
        {
          "quantity": 200,
          "_id": "62af007abb78a63a44e88563",
          "date_manufacture": ISODate("2022-04-01T10:45:01.711Z"),
          "date_expiration": ISODate("2023-05-11T10:45:06.882Z")
        }
      ]
    },
    {
      "_id": "62b3c2545a78fb4414dd718f",
      "locator": "62933e07c224b41fc48a1182",
      "imports": [
        {
          "quantity": 120,
          "_id": "62b3c2545a78fb4414dd7190",
          "date_manufacture": ISODate("2022-03-01T01:30:07.053Z"),
          "date_expiration": ISODate("2023-05-01T10:43:20.431Z")
        }
      ]
    }
  ]
}

然后,您可以做一些相对简单的事情:使用$sortArraydate_expiration进行排序,然后使用$reduce开始迭代数组。

db.inventory.aggregate([
  {
    $match: {
      locator: "62933b3fe744ac34445c4fc0"
    }
  },
  {
    "$set": {
      "imports": {
        $sortArray: {
          input: "$imports",
          sortBy: {
            date_expiration: 1
          }
        }
      }
    }
  },
  {
    $set: {
      result: {
        "$reduce": {
          "input": "$imports",
          "initialValue": {
            "qtyToDecrease": 300,
            "arr": []
          },
          "in": {
            "qtyToDecrease": {
              $subtract: [
                "$$value.qtyToDecrease",
                {
                  $min: [
                    "$$value.qtyToDecrease",
                    "$$this.quantity"
                  ]
                }
              ]
            },
            "arr": {
              "$concatArrays": [
                "$$value.arr",
                [
                  {
                    "$mergeObjects": [
                      "$$this",
                      {
                        "quantity": {
                          $subtract: [
                            "$$this.quantity",
                            {
                              $min: [
                                "$$value.qtyToDecrease",
                                "$$this.quantity"
                              ]
                            }
                          ]
                        }
                      }
                    ]
                  }
                ]
              ]
            }
          }
        }
      }
    }
  },
  {
    $set: {
      imports: "$result.arr",
      result: "$$REMOVE"
    }
  },
  {
    "$merge": {
      "into": "inventory",
      "on": "_id"
    }
  }
])

Mongo Playground
这里是another version,它保留了你原来的模式,你可以看到它要复杂得多。

相关问题