node.js - 如何在 mongodb/mongoose 的嵌套数组中检查是否存在并更新对象?
问题描述
我们正在尝试使用 node.js 和 typescript 为库存管理 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,
},
}
);
推荐阅读
- nlp - 在 pytorch 中保存模型输出
- tensorflow - 使用 Batch Normalization 和 Leaky ReLU 时的神经网络可解释性
- node.js - 如何解决我的 MERN 应用程序中的 Access-Control-Allow-Origin CORS 错误以进行 MSAL 身份验证?
- javascript - 如何阻止响应式表单验证器不在 OnInit 上触发?
- ms-word - 为什么 LibreOffice 不在 docx 文档中显示 AltChunks?
- angular - 角过渡动画ngIf:如何在:enter完成后触发:leave
- cadence-workflow - Uber Cadence 任务列表管理
- swift - 从嵌套容器中解码 JSON 并动态检查其类型以便在 swift 中进行类型转换
- c# - Linq 不支持 NotMapped 属性?
- java - 如果从不同的 JVMS 调用,系统 CPU 使用率的“SystemCpuLoad”会有所不同