簡體   English   中英

如何檢查存在並更新 mongodb/mongoose 中嵌套數組中的對象?

[英]How can I check existance and update an object in nested array in mongodb/mongoose?

我們正在嘗試使用 node.js 和打字稿為庫存管理 Web 應用程序構建 REST API。 我們的 Records>Stocks 文檔(嵌套數組)位於 Branches 集合下。

  • 記錄:使用桶模式保存數據。 這意味着分支機構一天只能擁有一個記錄文檔。
  • 股票:股票可以有像'TRANSFER' 或 'DAILY'這樣的類型 一個分行在一個記錄中只能有一個“每日”股票條目和許多“轉移”股票條目。

我們有庫存更新要求。 我們的Branches Collection示例文檔如下所示。

{
"phones": [
    "Lorem"
],
"_id": 2,
"name": "Üsküdar",
"address": {
    "city": "İstanbul",
    "address_line": "Cinali Sk. No:14 Selamiali 34664 ",
    "district": "Lorem"
},
"owner_id": 38,
"region_id": 12,
"totals": {
    "stock": {
        "P": -63,
        "K": 23,
        "U": -73
    },
    "sale": {
        "P": -28,
        "K": 82,
        "U": -36
    },
    "material": {
        "Kutu": 29,
        "Garnitur": 37,
        "Spatula": -55
    }
},
"records": [
    {
        "delivery": {
            "P": -18,
            "K": -69,
            "U": -15
        },
        "stocks": [
            {
                "time": "10:45",
                "quantity": {
                    "P": [
                        15
                    ],
                    "K": [
                        9
                    ],
                    "U": [
                        11
                    ]
                },
                "explanation": "Günlük Stok Girişi",
                "type": "DAILY"
            }
        ],
        "sales": [
            {
                "time": "Lorem",
                "quantity": {
                    "P": [
                        "Lorem"
                    ],
                    "K": [
                        "Lorem"
                    ],
                    "U": [
                        "Lorem"
                    ]
                },
                "explanation": "Lorem"
            }
        ],
        "material": [
            {
                "time": "Lorem",
                "quantity": {
                    "Kutu": -68,
                    "Garnitur": 42,
                    "Spatula": 4
                },
                "explanation": "Lorem"
            }
        ],
        "date": "16-09-2020"
    }
],
"orders": [
    {
        "date": "Lorem",
        "borek": {
            "quantity": {
                "P": 6,
                "K": 77,
                "U": -25
            },
            "status": "Lorem"
        },
        "material": {
            "quantity": {
                "Kutu": -43,
                "Garnitur": 29,
                "Spatula": -70
            },
            "status": "Lorem"
        }
    }
]}

我們的端點如下所示,它獲取 branch_id 並使用 req.body {"quantity": {"P": [11],"K": [4],"U": [4]}}創建一個請求

branchRouter.post(
  '/:branchId/daily-stock',
  async (req: Request, res: Response) => {
    const { branchId } = req.params;
    const { quantity } = req.body;

    const timestamp = moment().tz('Europe/Istanbul');
    const date = timestamp.format('DD-MM-YYYY');
    const time = timestamp.format('HH:mm');
    const explanation = 'Günlük Stok Girişi';
    const type = 'DAILY';
    const stockEntry = new Stock({ time, quantity, explanation, type });
    const recordEntry = new Record({ date, stocks: [stockEntry] });

    try {
      await Branch.findByIdAndUpdate(
        branchId,
        {},
        {
          new: true,
          projection: {
            'records.stocks': 1,
            'records.date': 1,
            // records: { $slice: 5 },  // to get first 5 array object
            records: { $elemMatch: { date: date } },
            'records.stocks.type': 1,
          },
          // arrayFilters: [{ 'records.stocks.type': { $eq: 'DAILY' } }],
        },
        async function (err: any, result: any) {
          if (err) {
            res.status(501).send('Branch cannot be updated!');
          } else {
            if (result) {
              if (result.records.length === 0) {
                await Branch.findByIdAndUpdate(branchId, {
                  $push: { records: recordEntry },
                });
                res.status(200).send({
                  message:
                    'No record found for today, it will be creating with daily-stock',
                  record: recordEntry,
                });
              } else {
                const entries = result.records[0].stocks;
                if (entries.some((stock: any) => stock.type === 'DAILY')) {
                  // TODO Update data by req.body, you can use something like $replacewith
                  await Branch.findByIdAndUpdate(branchId, {
                    'records.0.stocks': {
                      $cond: {
                        if: { $eq: ['$type', 'DAILY'] },                        
                        then: { $push: { 'records.$[].stocks': stockEntry } },
                        else: { $push: { 'records.$[].stocks': stockEntry } },
                      },
                    },
                    // $addToSet: { 'records.$.stocks': stockEntry },
                  });
                  res.status(200).send({
                    message: `Today's records and daily-stock exist, Daily-Stock Entry Updating...`,
                    record: result.records[0],
                  });
                } else {
                  await Branch.findByIdAndUpdate(
                    branchId,
                    { $push: { 'records.$[].stocks': stockEntry } },
                    {
                      projection: {
                        'records.stocks': 1,
                        records: { $elemMatch: { date: date } },
                      },
                    }
                  );
                  res.status(200).send({
                    message: `Today's records exists but not Daily-Stock, Daily-Stock Entry Inserting...`,
                    record: result.records[0],
                  });
                }
              }
            } else {
              res.status(404).send({ error: 'Branch not found!' });
            }
          }
        }
      );
    } catch (error) {
      res.status(400).send(error.message);
    }
  }
);

問題是如果我們已經有了,我們將如何更新今天的“每日”股票條目?

其實劇情有點難。 我們需要使用條件結構,但是$cond、$replaceWith、$push 等並沒有給出解決這個問題的想法。

我找到了,答案在這里

const dailyStockUpdatedBranch = await Branch.findOneAndUpdate(
                { _id: branchId },
                {
                  // $pull: {
                  //   'records.$[record].stocks.$[stock]': stockEntry,
                  // },
                  $set: {
                    region_id:
                      'records.$[record].stocks.$[stock].quantity.P[0]',
                  },
                },
                {
                  arrayFilters: [
                    { 'record.date': date },
                    { 'stock.type': 'DAILY' },
                  ],
                  projection: {
                    'records.stocks': 1,
                    'records.date': 1,
                    totals: 1,
                  },
                }
              );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM