Sin*_*tic 2 mongodb event-sourcing mongodb-.net-driver
这意味着将被读取为双重更新插入操作,首先更新插入文档,然后更新插入数组元素。
所以 MongoDB 对我来说是一个非规范化的存储(我们是事件源的),我试图处理的事情之一就是它的并发性。问题是这样的:
例如:
如果可能的话,让它作为单个原子操作执行将是理想的,但如果它只能通过多个步骤完成,那就这样吧。由于 2.x 驱动程序发生了巨大变化,我在网上得到了许多混合示例。不确定除了 UpdateOneAsync 之外我还在寻找什么。目前使用 2.4.x。解释的例子将不胜感激。TIA
注意:重申这是关于 MongoDB C# 驱动程序 2.4.x 的问题
做了一些修补,但我明白了。
var notificationData = new NotificationData
{
ReferenceId = e.ReferenceId,
NotificationId = e.NotificationId,
DeliveredDateUtc = e.SentDate.DateTime
};
var matchDocument = Builders<SurveyData>.Filter.Eq(s => s.SurveyId, e.EntityId);
// first upsert the document to make sure that you have a collection to write to
var surveyUpsert = new UpdateOneModel<SurveyData>(
matchDocument,
Builders<SurveyData>.Update
.SetOnInsert(f => f.SurveyId, e.EntityId)
.SetOnInsert(f => f.Notifications, new List<NotificationData>())){ IsUpsert = true};
// then push a new element if none of the existing elements match
var noMatchReferenceId = Builders<SurveyData>.Filter
.Not(Builders<SurveyData>.Filter.ElemMatch(s => s.Notifications, n => n.ReferenceId.Equals(e.ReferenceId)));
var insertNewNotification = new UpdateOneModel<SurveyData>(
matchDocument & noMatchReferenceId,
Builders<SurveyData>.Update
.Push(s => s.Notifications, notificationData));
// then update the element that does match the reference ID (if any)
var matchReferenceId = Builders<SurveyData>.Filter
.ElemMatch(s => s.Notifications, Builders<NotificationData>.Filter.Eq(n => n.ReferenceId, notificationData.ReferenceId));
var updateExistingNotification = new UpdateOneModel<SurveyData>(
matchDocument & matchReferenceId,
Builders<SurveyData>.Update
// apparently the mongo C# driver will convert any negative index into an index symbol ('$')
.Set(s => s.Notifications[-1].NotificationId, e.NotificationId)
.Set(s => s.Notifications[-1].DeliveredDateUtc, notificationData.DeliveredDateUtc));
// execute these as a batch and in order
var result = await _surveyRepository.DatabaseCollection
.BulkWriteAsync(
new []{ surveyUpsert, insertNewNotification, updateExistingNotification },
new BulkWriteOptions { IsOrdered = true })
.ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
被链接为骗子的帖子绝对有帮助,但这不是答案。有一些事情需要被发现。
链接示例中的“第二条语句”无法正常工作,至少在按字面翻译时是这样。为了让它工作,我必须匹配元素,然后通过将其包装在 Not() 过滤器中来反转逻辑。
为了在匹配中使用“此索引”,您必须在数组上使用负索引。事实证明,在呈现查询时,C# 驱动程序会将任何负索引转换为“$”字符。
为了确保它们按顺序运行,您必须包含IsOrdered设置为 true 的批量写入选项。
| 归档时间: |
|
| 查看次数: |
947 次 |
| 最近记录: |