如何使用公式(或表达式)使用 Mongo DB C# Drivers 4.2 更新值?

How to use formula (or Expression) to update value using Mongo DB C# Drivers 4.2?

我对 MongoDb(和 MongoDb C# 驱动程序)很陌生,最近,我们正在尝试实施更新,其中我们使用字段值和变量(方法参数)更新几个字段。

基本上,我们的文档是这样的

public class Inventory {

public string _id;

public decimal Quantity;

public decimal TotalCost;

}

我们要做的是根据传递的值 (qty) 更新数量和总成本。

(1) TotalCost -= (qty * (TotalCost / Quantity))

(2) 数量 -= 数量

这背后的逻辑是我们要保留商品的平均成本。 注意:步骤(1)中数量字段的值应该使用原始值,而不是步骤(2)的结果。

我们可以使用 2 个查询来实现这个,但在我们的例子中,我们只需要在一次调用中执行这个逻辑,因为有不同的线程将更新单个项目。

我已经阅读了关于聚合和投影(以及使用表达式)的文档,但我似乎无法弄清楚如何使用投影结果或将投影结果组合到聚合更新中。

尝试将此投影到 return 应该从 totalCost

中扣除的值

Builders.Projection.Expression(e => (e.totalCost / e.quantity) * -qty);

谢谢,希望你们能为我们指明正确的方向。

这相当于我们在 mongo shell 中试图实现的目标,前提是数量 = 500。

db.inventory.updateOne( { _id: "1" }, [ { "$set": { "TotalCost": { "$add": ["$TotalCost", { "$multiply": [-500, { "$divide": ["$TotalCost", "$Quantity"] }] }] } } } ] )

目前没有用于创建更新管道的类型安全的辅助方法。但是,您可以像使用控制台一样使用相同的 json-ish 语法。这是一些示例 C# 代码。

// Some id to filter on
var id = ObjectId.GenerateNewId();


var db = client.GetDatabase("test");
var inventory = db.GetCollection<Inventory>("inventory");


var filter = Builders<Inventory>.Filter
    .In(x => x.Id, id);

var update = Builders<Inventory>.Update.Pipeline(
    new PipelineStagePipelineDefinition<Inventory, Inventory>(
        new PipelineStageDefinition<Inventory, Inventory>[]
        {
            @"{ ""$set"": { ""TotalCost"": { ""$add"": [""$TotalCost"", { ""$multiply"": [-500, { ""$divide"": [""$TotalCost"", ""$Quantity""] }] }] } } }",
        }));

await inventory.UpdateOneAsync(filter, update)
    .ConfigureAwait(false);