javascript - 根据文档中数组元素的值和文档本身的_id更新文档
问题描述
正如问题所述,我无法让此更新操作正常工作。
我的场景:
我有一个Event
,一个Ticket
和一个TicketPurchase
。和具有Event
数组作为属性。TicketPurchase
Ticket
我需要达到的目标:
更新from true/false的票证数组中
validated
特定的属性。Ticket
TicketPurchase
total_quantity
将主表中同一张票的属性从1.递减Event
。(a中的所有票TicketPurchase
都是主表中票的副本Event
)
作为一名程序员,我几乎所有的经验都花在了使用 MySQL 上,所以我仍然是 NoSQL 世界的初学者。
我试过的:
- 检查了文档
- 在 S/O 上花了一些时间,这被证明是最相关的答案,但我无法让这个解决方案发挥作用。
- 交换了我对 and 的用法
id
,_id
将运算符$set
放入和取出 ' ' 标记,以及所有其他类似的配置,什么都不会。
票务.js
const TicketSchema = new Schema({
type : {type: String},
total_quantity : {type: Number},
price : {type: String},
limit_per_order: {type: Number},
start_date: {type: Date},
end_date: {type: Date},
description: {type: String},
validated: {type: String, default: 'false'}
});
事件.js
const EventSchema = new Schema({
title: {type: String},
location: {type: String},
start_date: {type: Date},
start_time: {type: String},
end_date: {type: Date},
end_time: {type: String},
description: {type: String},
organizer_name: {type: String},
organizer_about: {type: String},
cover_picture: {type: String},
tickets: [{type: Schema.Types.ObjectId, ref: 'Ticket'}],
access_code: {type: String, default: shortid.generate}
});
ticketPurchase.js
const TicketPurchaseSchema = new Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'},
event: {type: Schema.Types.ObjectId, ref: 'Event'},
tickets: [{type: Schema.Types.ObjectId, ref: 'Ticket'}],
time_stamp: {type: Date}
});
更新.js
for(var x of ticketPurchase.tickets){
//console.log(x);
if(x.id === ticket_id && x.validated === 'false'){
console.log('ticket not validated. Update');
TicketPurchase.update(
{_id: ticket_purchase_id, 'tickets._id': ticket_id},
{'$set':{
'tickets.$.validated': 'true'
}},
function (err){
console.log('updated validated');
if(err){console.log(err);}
}
);
Event
.update({_id: event_id, "tickets._id": x.id},
{$inc : {"tickets.$.total_quantity" : -1}});
console.log('updated ticket.total_qty');
payload['success'] = 'true';
}else if(x.id === ticket_id && x.validated === 'true'){
console.log('ticket validated');
payload['success'] = 'false';
payload['message'] = 'Ticket already validated.';
}
}
解决方案
首先,这是一个简短的示例,说明如何避免循环并仅使用 mongoose 方法完成所有操作:
TicketPurchase.findById(purchaseId, (err, ticketPurchase) => {
Ticket.update({ _id: { $in: ticketPurchase.tickets }, _id: ticket_id, validated: 'false' },
{ $set: { validated: 'true' }, $inc: { total_quantity: -1 } },
(err, outcome) => {
console.log(`The number of validated tickets for the Purchase #${purchaseId} is ${outcome.nModified}`);
});
});
在这里,它在同一操作中完成所有操作:找到属于购买但尚未验证的票,然后将验证的属性设置为“真”并减少数量。最后,您将获得修改记录的总数。
In your example I can't see that you've populated your tickets in the purchaseTicket. To iterate through ticket objects in the manner you wrote, you'd be compelled to populate it for their parent entity since the property ticketPurchase.tickets
contains only references. The expression would look like: TicketPurchase.findById(purchaseId).populate('tickets').then(purchase => { ... })
Where purchase
has the property tickets
filled up with its ticket objects instead of merely id objects.
Adding to that, you seem not to have to update tickets in the Event schema since you can do it directly in the Ticket schema (just like I did in my example overhead) since all the references eventually point out to their objects in the schema.
推荐阅读
- javascript - 使用 Socket.io + Puppeteer + Node.js 创建带有 HTML 和 CSS 的 PDF
- java - imageView 不显示来自外部存储的图像
- mysql - Mysql,每周一和周二插入查询
- swift - 处理未知的 UTF8 字符
- d3.js - attr() 不会更改属性,除非我通过匿名函数返回它
- javascript - 问题倍数计数器编号同一页
- javascript - 清除 Buefy 日期选择器
- postgresql - jooq UTC localdatetime 在保存和加载之间更改
- c# - 如何解决:无法将 system.collections.generic.list 隐式转换为 system.collections.generic.ienumerable
- php - 将数据表中的数据添加到 laravel 中的模态