如何使用mongoDB / mongoose聚合管道将自定义字段的聚合值设置为?

问题描述 投票:0回答:2

我正在开发购物车,我目前的要求是向店主展示仪表板。由于产品名称可能存在重复,因此我将产品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”:“字段'标题'必须是累加器对象”,“ok”:0,“errmsg”:“字段'标题'必须是累加器对象”,“代码 “:40234,” 代号 “:” Location40234" }

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

node.js mongodb mongoose
2个回答
1
投票

我相信问题可能在你的group运营商。具体来说,你正在做title: "$orderedProducts.title",这可能会导致分组问题。 MongoDB可能不理解如何处理这种情况,因为无法确定要使用哪个文档的标题的优先级。这就是为什么需要某种形式的累加器,例如你在$sum领域使用的qty

相反,尝试省略分组的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);
    });

0
投票

在组管道中使用$ 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保持一致。所以你可以选择与最终分组对象相连的第一个或最后一个

© www.soinside.com 2019 - 2024. All rights reserved.