mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询
Posted
技术标签:
【中文标题】mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询【英文标题】:mongoDB, mongoose aggregation query with $sum and $count 【发布时间】:2021-08-23 00:26:15 【问题描述】:世界! 我是 mongodb 的新手,我不知道我可以通过聚合和求和等来完成这项任务..( 所以,我有这个系列: 这是商店集合
"storeName": "store one",
"_id" : ObjectId("store id 1"), // this is store ID
"shopId" : ObjectId("shopId 1"),
"shopItems" : [
"_id" : ObjectId("6048a1fa31d779032b16301e"),
"itemId" : ObjectId("111"), // this is product id from PRODUCTS collection
"itemCount" : 2
,
"_id" : ObjectId("6048a46e31d779032b163043"),
"itemId" : ObjectId("222"),// this is product id from PRODUCTS collection
"itemCount" : 0
],
,
"storeName": "store two"
"_id" : ObjectId("storeId 2"), // this is store ID
"shopId" : ObjectId("shopId 2"),
"shopItems" : [
"_id" : ObjectId("6048a1fa31d779032b16301e"),
"itemId" : ObjectId("222"), // this is product id from PRODUCTS collection
"itemCount" : 2
,
"_id" : ObjectId("6048a46e31d779032b163043"),
"itemId" : ObjectId("333"),// this is product id from PRODUCTS collection
"itemCount" : -5
"_id" : ObjectId("6048a46e31d779032b163043"),
"itemId" : ObjectId("111"),// this is product id from PRODUCTS collection
"itemCount" : -7
],
这是产品集合,这是一个不同价格的数组, 实际上还有更多〜50/50。我收集了 boolean 表示商店的价格 是不同的(也许对任务有帮助)
// products collection
"_id" : ObjectId("111"), // itemId in STORE collection
"differentPricesForShops" : false,
"productName" : "some name here",
"buyPrice" : 10,
"sellingPrice" : 100,
"differentPricesForShops" : false,
"difPriceArray" : []
,
"_id" : ObjectId("222"), // itemId in STORE collection
"differentPricesForShops" : false,
"productName" : "some name here",
"differentPricesForShops" : true, <- TRUE
"difPriceArray" : [
"shopId": ObjectId("shopId1") <- shop
"buyPrice" : 5, <- differentPrices
"sellingPrice" : 50,
,
"shopId": ObjectId("shopId 2")
"buyPrice" : 15,
"sellingPrice" : 55,
,
]
,
"_id" : ObjectId("333"), // itemId in STORE collection
"differentPricesForShops" : false,
"productName" : "some name here",
"buyPrice" : 5,
"sellingPrice" : 15,
"differentPricesForShops" : false,
"difPriceArray" : []
,
我需要这个输出数据:
"shopId" : ObjectId("6048a15031d779032b16300f"),
产品数量:2,
产品负数:0,
selfprice: (2-> 店内计数 * 10(buyPrice) ) = 20
待售产品:(2 -> 店内数量 * 100(售价))= 200
"shopId" : ObjectId("6048a15031d779032b16300f"),
产品数量:2,
减号产品:-5(店内商品数)+ -7(店内商品数)= -12
selfprice:(2-> 店内数 * 15(不同店价))= 30
待售产品:(2 -> 店内数量 * 55(各店价格不同))= 110
这个例子是按 1 个产品,但 我需要有 selfPrice 和待售产品的总和。 请检查图片 我需要这样显示数据:
data in table img
我希望有人可以帮助我。非常感谢!
【问题讨论】:
【参考方案1】:此聚合查询将为您提供所需的输出:
管道阶段:
unwind : 这将为给定商店的每个产品创建单独的文档
lookup : 这将用于连接和获取产品详细信息
unwind : 因为查找结果是数组,所以将它作为文档/对象
addfields:检查价格是否存在差异,然后设置适当的值
addfields:将上述步骤中匹配的商店 $buyPrice 和 $ sellPrice 从对象转换为字段
addfields:根据上述步骤中的 $buyPrice 和 $ sellPrice 设置 selfprice 和 products_for_sale
组:以我们想要的方式提取字段!
[$unwind:
path: '$shopItems'
, $lookup:
from: 'products',
localField: 'shopItems.itemId',
foreignField: '_id',
as: 'shop_products'
, $unwind:
path: '$shop_products'
, $addFields:
buyPrice: $cond: if: $anyElementTrue:["$shop_products.difPriceArray"],
then:
$arrayElemAt:[$filter:
input: "$shop_products.difPriceArray",
as: "item",
cond: $eq: [ "$$item.shopId", '$shopId' ]
,0]
,
else: '$shop_products.buyPrice',
sellingPrice: $cond: if: $anyElementTrue:["$shop_products.difPriceArray"],
then:
$arrayElemAt:[$filter:
input: "$shop_products.difPriceArray",
as: "item",
cond: $eq: [ "$$item.shopId", '$shopId' ]
,0],
else: '$shop_products.sellingPrice',
, $addFields:
buyPrice: $cond: if: $eq: [$type: '$buyPrice',"object"] , then: '$buyPrice.buyPrice' ,else:'$buyPrice',
sellingPrice: $cond: if: $eq: [$type: '$sellingPrice',"object"] , then: '$sellingPrice.sellingPrice' ,else:'$sellingPrice'
, $addFields:
selfprice: $multiply: [ $ifNull:['$shopItems.itemCount',0], $ifNull:[ '$buyPrice',0]] ,
products_for_sale : $multiply: [ $ifNull:['$shopItems.itemCount',0], $ifNull:[ '$sellingPrice',0]] ,
, $group:
_id: '$_id',
selfprice:$sum:
$cond: if: $lt: [ "$selfprice", 0 ] , then: 0, else: '$selfprice'
,
product_count:$sum:1,
shopId:$first:'$shopId',
product_in_minus:$sum:
$cond: if: $lt: [ "$shopItems.itemCount", 0 ] , then: "$shopItems.itemCount", else: 0
,
products_for_sale:$sum:
$cond: if: $lt: [ "$products_for_sale", 0 ] , then: 0, else: '$products_for_sale'
]
Mongo 游乐场:https://mongoplayground.net/p/P7xYYEQBJ-J
【讨论】:
以上是关于mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB相当于MySQL:select count(*) c, sum(if(x='A',1,0)) as a, sum(if(x='B',1,0)) as b
《MongoDB入门教程》第24篇 聚合统计之$count表达式