根据文档中数组元素的值和文档本身的_id更新文档
Posted
技术标签:
【中文标题】根据文档中数组元素的值和文档本身的_id更新文档【英文标题】:Updating a doc based on the value of an array element in the doc and the _id of the doc itself 【发布时间】:2019-03-23 10:38:10 【问题描述】:正如问题所述,我无法让此更新操作正常工作。
我的场景:
我有一个Event
、一个Ticket
和一个TicketPurchase
。 Event
和 TicketPurchase
具有 Ticket
数组作为属性。
我需要达到的目标:
将TicketPurchase
的票证数组中特定Ticket
的validated
属性从真/假更新。
从主表Event
中的1. 减少同一票证的total_quantity
属性。(TicketPurchase
中的所有票证都是主表Event
中票证的副本)
作为一名程序员,我几乎所有的经验都花在了使用 mysql 上,所以我仍然是 NoSQL 世界的初学者。
我尝试过的:
-
Checked the docs
在 S/O 上花了一些时间,this 被证明是最相关的答案,但我无法让这个解决方案发挥作用。
交换了我对
id
和_id
的用法,将$set
之类的运算符放入和取出' ' 标记,以及所有其他类似的配置,什么都不会。
ticket.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'
);
event.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
);
update.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.';
【问题讨论】:
【参考方案1】:首先,这是一个简短的示例,说明如何避免循环并仅使用 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`);
);
);
在这里,它在同一操作中完成所有操作:找到属于购买但尚未验证的票,然后将验证的属性设置为“真”并减少数量。最后,您将获得修改记录的总数。
在您的示例中,我看不到您已在 purchaseTicket 中填充了您的票。要以您编写的方式遍历票证对象,您将不得不为其父实体填充它,因为属性 ticketPurchase.tickets
仅包含引用。表达式看起来像:TicketPurchase.findById(purchaseId).populate('tickets').then(purchase => ... )
其中purchase
的属性tickets
填充了它的票证对象,而不仅仅是id 对象。
除此之外,您似乎不必更新 Event 架构中的票证,因为您可以直接在票证架构中进行更新(就像我在示例开销中所做的那样),因为所有引用最终都指向它们的对象架构。
【讨论】:
谢谢你简洁的解释和代码先生。以上是关于根据文档中数组元素的值和文档本身的_id更新文档的主要内容,如果未能解决你的问题,请参考以下文章