繁体   English   中英

如何使用mongoDB / mongoose聚合管道基于定制字段的聚合值?

[英]How can I have the aggregated values based with custom fields using mongoDB/mongoose aggregation pipeline?

我正在开发一个购物车,目前的要求是向商店老板显示一个仪表板。 由于产品名称可能重复,因此我将订购的产品按产品ID分组,并执行总和以获得订单总数。 现在,我还需要可读的名​​称,但这样做会引发错误。

查询

ShoppingCart
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } })
    .project("orderedProducts.productID orderedProducts.title  orderedProducts.qty -_id")
    .unwind("orderedProducts")
    .group({ _id: "$orderedProducts.productID", counts: { $sum: "$orderedProducts.qty" }, title: "$orderedProducts.title" })
    .exec((err, docs) => {
        if (err) {
            return res.status(503).send(err);
        }
        res.send(docs);
    });

错误信息 :

{“ name”:“ MongoError”,“ message”:“字段'title'必须是累加器对象”,“ ok”:0,“ errmsg”:“字段'title'必须是累加器对象”,“代码 “:40234,” 代号 “:” Location40234" }

这是导致错误标题的部分:“ $ orderedProducts.title”

我相信问题可能出在您的group操作员身上。 具体来说,您正在执行title: "$orderedProducts.title" ,这可能会导致分组问题。 MongoDB可能不了解如何处理这种情况,因为无法确定使用哪个标题的优先级。 这就是为什么需要某种形式的累加器的原因,例如,您在qty字段上使用的$sum

相反,请尝试省略分组的title部分,而使用复合_id

ShoppingCart
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } })
    .project("orderedProducts.productID orderedProducts.title  orderedProducts.qty -_id")
    .unwind("orderedProducts")
    .group({ _id: { productId: "$orderedProducts.productID", title: "$orderedProducts.title" }, counts: { $sum: "$orderedProducts.qty" } })
    .exec((err, docs) => {
        if (err) {
            return res.status(503).send(err);
        }
        res.send(docs);
    });

该解决方案的警告是,它假定每个productID仅只有一个标题。 它将按productIDtitle分组,因此同一productID任何不同标题都将导致此解决方案失败。 如果这对您来说是个问题,而您想获取给定productID所有产品标题,则可以执行以下操作:

ShoppingCart
    .aggregate({ $match: { "orderedProducts.registrationDetails.createdByID": LOGGED_IN_ADMIS_ID } })
    .project("orderedProducts.productID orderedProducts.title  orderedProducts.qty -_id")
    .unwind("orderedProducts")
    .group({ _id: "$orderedProducts.productID", counts: { $sum: "$orderedProducts.qty" }, titles: { $addToSet: "$orderedProducts.title" } })
    .exec((err, docs) => {
        if (err) {
            return res.status(503).send(err);
        }
        res.send(docs);
    });

在组管道中使用$ last或$ first

.group({ 
     _id: "$orderedProducts.productID", 
     counts: { $sum: "$orderedProducts.qty" }, 
     title: { $first:"$orderedProducts.title"} 
})

要么,

.group({ 
     _id: "$orderedProducts.productID", 
     counts: { $sum: "$orderedProducts.qty" }, 
     title: { $last:"$orderedProducts.title"} 
})

由于您要对产品进行分组,因此标题应保持与相似的product_id相对。 因此,您可以选择第一个或最后一个与最终分组对象相连的对象

暂无
暂无

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

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