MongoDB聚合 - 嵌套Schema内部的$ match作为数组吗?

时间:2018-02-06 21:25:42

标签: node.js mongodb mongoose schema aggregation

我想在mongoDB的聚合操作中使用$ sum操作。但是,嵌套Schema中有一个字段,它也是我必须检查的数组。

这是我的顶级架构购物车:



const CartSchema = new Schema({
    created_at: { type: Date, default: moment() },
    updated_at: { type: Date, default: moment(), expires: 300 },
    cartitems: [{ type : Schema.Types.ObjectId, ref : 'cartitem'}],
    user: {
        type: Schema.Types.ObjectId,
        ref: 'user'
    },
});




这是CartItemSchema:



const CartItemSchema = new Schema({
    cart : {
        type : Schema.Types.ObjectId,
        ref : 'cart'
    },
    product : {
        type : Schema.Types.ObjectId,
        ref : 'product'
    },
    created_at : { type : Date, default : moment() },
    quantity : Number
});




这是我的聚合函数:



CartSchema.statics.findStockFromCarts = function (productId) {

    return this.aggregate([
        { $unwind : "$cartitems" },
        { $match : { "cartitems" : { "product" :{  "$oid" : productId } } }},
        {
            $group: {   
                "_id" : "$oid",
                total: {
                    $sum: "cartitems.quantity",                    
                }
            }
        }
    ])

}




实际行为是它返回一个空数组。

预期的行为是它必须返回这些购物车中产品的总数量。

mLab的结果:



{
    "_id": {
        "$oid": "5a7a2ac99f12ff0874be3e0c"
    },
    "created_at": {
        "$date": "2018-02-06T22:22:47.913Z"
    },
    "updated_at": {
        "$date": "2018-02-06T22:23:05.779Z"
    },
    "cartitems": [
        {
            "created_at": {
                "$date": "2018-02-06T22:22:47.915Z"
            },
            "_id": {
                "$oid": "5a7a2aca9f12ff0874be3e0d"
            },
            "quantity": 1,
            "product": {
                "$oid": "5a76449c852bcd2427911fba"
            }
        }
    ],
    "__v": 1
}




创建此文档的查询!



CartSchema.statics.addItem = function (cartId, productId, quantity) {
    console.log("CartSchema addItem : cartId : " + cartId);
    console.log("CartSchema addItem : item : " + productId);
    console.log("CartSchema addItem : quantity : " + quantity);
    const CartItem = mongoose.model('cartitem');
    return this.findById(cartId)
        .then(cart => {
            const cartitem = new CartItem({ quantity });
            cartitem.product = productId;
            console.log("CartSchema addItem : cartItem : " + cartitem);
            console.log("CartSchema addItem : cartItem.id " + cartitem.id)
            cart.cartitems.push(cartitem);
            console.log("CartSchema addItem : cart total : " + cart)
            return Promise.all([
                cart.save()
            ]).then(([cart]) => cart);
        })
};




1 个答案:

答案 0 :(得分:1)

在应用匹配条件之前,您必须填充购物车项目。

$lookup阶段用于根据匹配的cartitems数组,然后$unwind$match从购物车项目集合中提取数据,以便为匹配的产品提供查询条件。

$group阶段总和输出数量总计。

this.aggregate([
{"$lookup":{
  "from":"cartitems", // name of the collection, not model or schema name
  "localField":"cartitems",
  "foreignField":"_id",
  "as":"cartitems"
}},
{"$unwind":"$cartitems"},
{"$match":{"cartitems.product":mongoose.Types.ObjectId(productId)}},
{"$group":{
  "_id":"$_id",
  "total":{"$sum":"$cartitems.quantity"}
}}])