简体   繁体   English

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

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

I am quite new to MongoDb (and MongoDb C# Drivers) and lately, we are trying to implement an update wherein we use the value of a field and a variable (method parameter) to update several fields.我对 MongoDb (和 MongoDb C# 驱动程序)很陌生,最近,我们正在尝试实现一个更新,其中我们使用一个字段的值和一个变量来更新几个字段(方法)。

Basically, our doc is something like this基本上,我们的文档是这样的

public class Inventory {公共 class 库存 {

public string _id;公共字符串_id;

public decimal Quantity;公开十进制数量;

public decimal TotalCost;公共小数 TotalCost;

} }

What we want to do is to update the quantity and totalCost based on a passed value (qty).我们要做的是根据传递的值 (qty) 更新数量和总成本。

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

(2) Quantity -= Qty (2) 数量 -= 数量

The logic behind this is that we want to retain the average cost of our item.这背后的逻辑是我们希望保留商品的平均成本。 Take note: the value of quantity field in step (1) should use the original value and not the result of step (2).注意:步骤(1)中数量字段的值应使用原始值,而不是步骤(2)的结果。

We can implement this using 2 queries but in our case, we need to execute this logic in one call only as there are different threads that will update a single item.我们可以使用 2 个查询来实现这一点,但在我们的例子中,我们只需要在一次调用中执行这个逻辑,因为有不同的线程会更新单个项目。

I have read the docs about Aggregate and Projection (and using Expressions) but I cannot seem to figure out how to use or combine the result of projection into the aggregate update.我已阅读有关聚合和投影(以及使用表达式)的文档,但我似乎无法弄清楚如何使用或将投影结果组合到聚合更新中。

Tried this projection to return the value that should be deducted from totalCost尝试此投影以返回应从 totalCost 中扣除的值

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

Thank you and hope you guys can point us in the right direction.谢谢你们,希望你们能指出我们正确的方向。

Here is an equivalent of what we are trying to achieve in mongo shell, provided that qty = 500.这是我们在 mongo shell 中尝试实现的等价物,前提是 qty = 500。

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

There's currently no type-safe helper methods for creating update pipelines.目前没有用于创建更新管道的类型安全的辅助方法。 However, you can just use the same json-ish syntax like you do with the console.但是,您可以使用与控制台相同的 json-ish 语法。 Here's bit of example C# code.这是 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM