mongodb - 如何在更新时间 MongoDb 中将字段的总值添加为预聚合字段?
问题描述
我知道在 Mongo 中使用 $inc 可以计算和更新更新时间的数据计数,例如:
db.flights.update(
{
$inc: {totalCnt: 1}
$push: { price: {'t': time, 'p': newValue },
$setOnInsert: { flightNo: "EN120" , airline="LFT"}
},
{ upsert: true }
)
但是,我还需要计算price.p的总值(在上面的示例中)并将其添加并存储为更新时间的字段。我想知道是否可以在更新中使用 $sum 或 $add ?(实际上我希望能够在更新时间将平均价格存储为预聚合字段)。
例如,假设此文档存在于航班集合中:
{ "_id" : 1, "flightNo" : "EN120", "airline" : "LFT", "price" : [{"t": 120, "p": 2500}]}
执行更新(假设时间和价格的新值分别为130和3000)命令后我需要的结果是:
{ "_id" : 1, "flightNo" : "EN120", "airline" : "LFT", "price" : [{'t': 120, 'p': 2500}, {'t': 130, 'p': 3000}], "totalCnt":2, "totalPrice": 5500}
在使用t=150和p=2850执行另一个更新后,结果应该是:
{ "_id" : 1, "flightNo" : "EN120", "airline" : "LFT", "price" : [{'t': 120, 'p': 2500}, {'t': 130, 'p': 3000}, {'t': 150, 'p': 2850}], "totalCnt":3, "totalPrice": 8350}
谢谢
解决方案
对于 Mongo v4.2+,您可以使用流水线更新,请注意,您必须像这样更改更新结构:
db.collection.updateOne(
{ query },
[
{
$set: {
airline: {$ifNull: ["$airline", "LFT"]},
flightNo: {$ifNull: ["$flightNo", "EN120"]},
price: {$concatArrays: [{$ifNull: ["$price", []]}, [{'t': time, 'p': newValue}]]},
}
},
{
$set: {
totalPrice: {
$reduce: {
input: "$price",
initialValue: 0,
in: {$sum: ["$$this.p", "$$value"]}
}
},
totalCnt: {$size: "$price"}
}
}
],
{
upsert: true
}
)
对于较小的版本,您必须将其拆分为 2 个调用。首先获取,在代码中进行计算,然后更新。
- - 编辑 - -
一种更有效的计算方法totalPrice
:
db.collection.updateOne(
{ query },
[
{
$set: {
flightNo: {$ifNull: ["$flightNo", "EN120"]},
totalPrice: {$sum: ["$totalPrice", newValue]},
price: {$concatArrays: [{$ifNull: ["$price", []]}, [{'t': time, 'p': newValue}]]},
}
},
{
$set: {
totalCnt: {$size: "$price"}
}
}
],
{
upsert: true
}
)
推荐阅读
- javascript - 如何使用 ReactJS 避免递归方法中的许多重新渲染
- mysql - PowerApps MySl - 下拉问题
- reactjs - 从 HashRouter 更改为 browserRouter 后,React router 4 路由停止工作
- r - R中不同行中相同字符串的总和
- php - 在父子类别中显示父子类别的其他子类别
- python - 对齐可迭代:错误“字符串无法从手动字段规范切换到自动字段编号”
- facebook - 使用 Fb SDK 使用 Facebook 进行 Cognito 登录
- typescript - 如何从 index.d.ts 中的@types 导入接口?
- javascript - 不能增加 - 减少字体大小
- reactjs - Reactjs + Redux Form FieldArray 条件渲染