[英]Mongodb aggregation or projection
{ "items": [ { "id": "5bb619e49593e5d3cbaa0b52", "name": "Flowers", "weight": "1.5" }, { "id": "5bb619e4ebdccb9218aa9dcb", "name": "Chair", "weight": "8.4" }, { "id": "5bb619e4911037797edae511", "name": "TV", "weight": "20.8" }, { "id": "5bb619e4504f248e1be543d3", "name": "Skateboard", "weight": "5.9" }, { "id": "5bb619e40fee29e3aaf09759", "name": "Donald Trump statue", "weight": "18.4" }, { "id": "5bb619e44251009d72e458b9", "name": "Molkkÿ game", "weight": "17.9" }, { "id": "5bb619e439d3e99e2e25848d", "name": "Helmet", "weight": "22.7" } ] }
我有这种结构的模型。 我想计算每个订单的重量。 我应该使用聚合还是有人有任何想法?
这是订单的示例:
{
"id": "5bb61dfd4d64747dd8d7d6cf",
"date": "Sat Aug 11 2018 02:01:25 GMT+0000 (UTC)",
"items": [
{
"item_id": "5bb619e44251009d72e458b9",
"quantity": 4
},
{
"item_id": "5bb619e4504f248e1be543d3",
"quantity": 2
},
{
"item_id": "5bb619e40fee29e3aaf09759",
"quantity": 3
}
]
}
您在这里有两个选择,而无需更改模型结构:
Parcel
使用的所有项目 $lookup
)在数据库端执行所有计算 这很大程度上取决于您的实际数据模型和数据集大小。 第一种选择非常简单明了,在大型数据集上可能表现得更好,尤其是在涉及分片/副本集时。 但是它需要更多的数据库往返,这将带来更多的延迟。 另一方面,在某些情况下,聚合在查找时可能会非常慢。 但是唯一的好方法是对您的真实数据进行测试。 如果您当前的数据集很小(例如100 Mb),请选择您喜欢的方式-两者都将非常有用。
更新
由于您需要将Orders
分发到Parcels
我仍然希望选择选项1,尽管仍然可以使用汇总。
这就是我要做的:
Order
Order.items
找到的ID从数据库中提取所有相关Items
Order
重量的计算 Parcel
,并将其保存到数据库中 Parcels
某种方式将Items
分发到Parcels
并将其保存到数据库 请注意,您可以在一个调用中通过如下查询通过其ID提取多个Items
:
{
_id: { $in: [<id1>, <id2>] }
}
还有另一件事要考虑。 请注意MongoDB没有事务或多文档原子性这一事实。 因此,使用模式定义的显示方式执行这种类型的操作(从数据库中抽取内容,执行计算并存储回去)会导致创建重复项。
您可以使用以下aggregation
db.order.aggregate([
{ "$unwind": "$items" },
{ "$lookup": {
"from": "items",
"localField": "items.item_id",
"foreignField": "id",
"as": "item"
}},
{ "$unwind": "$item" },
{ "$addFields": { "items.weight": "$item.weight" }},
{ "$group": {
"_id": "$_id",
"items": { "$push": "$items" },
"date": { "$first": "$date" }
}}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.