【问题标题】:Getting array of group _id while using MongoDB使用 MongoDB 时获取组 _id 的数组
【发布时间】:2020-08-22 06:42:21
【问题描述】:

我需要在 mongoDB 中使用 group 计算一些记录,但在我的情况下,_id 数组即将到来。我在下面解释我的查询。

let query = {
      $group: {
             _id:  "$Products.ProductName",
             dispatchcount: { $sum: 1 },
             totalDispatchValue: {$sum:"$TotalAmount.TotalPayment"},
             totalDiscountValue: {$sum: "$TotalDiscount.TotalDiscountAmount"}
      }
}
pipeLine.push(query);
const orders = await dispatchOrdersCol.aggregate(pipeLine);

实际输出:

[
            {
                "_id": [
                    "Unisex Navy Blue Belt"
                ],
                "dispatchcount": 1,
                "totalDispatchValue": 27922,
                "totalDiscountValue": 4084
            },
            {
                "_id": [
                    "Writing Ruled Note Book",
                    "Physics Record Book",
                    "Chemistry Record Book",
                    "Computer Science Record Book"
                ],
                "dispatchcount": 1,
                "totalDispatchValue": 2190,
                "totalDiscountValue": 0
            },
            {
                "_id": [
                    "PU2-Physics Part-1 Text Book",
                    "PU2-Physics Part-2 Text Book",
                    "PU2-Mathematics Part - 1 Text Book",
                    "PU2-Chemistry Part - 1 Text Book",
                    "PU2-English Text Book",
                    "PU2-Mathematics Part - 2 Text Book",
                    "PU2-Chemistry Part - 2 Text Book",
                    "PU2-English Work Book",
                    "PU2-TEXT BOOK",
                    "PU2-Sanskrit Text Book",
                    "Boys White & Blue Striped Half Shirt",
                    "Boys Navy Blue Regular Fit Trousers",
                    "Illume Calf-length Cotton Black Socks  "
                ],
                "dispatchcount": 1,
                "totalDispatchValue": 4131,
                "totalDiscountValue": 150
            },
            {
                "_id": [
                    "PU2-TEXT BOOK"
                ],
                "dispatchcount": 1,
                "totalDispatchValue": 1679,
                "totalDiscountValue": 0
            }
        ]

这里对于_id 键有多个值,其中一些值还在下一条记录中重复。

猫鼬模型:

const Model = new Schema({
        DispatchId: { type: Number, required: true },
        OrderNumber: { type: String, unique: true, required: true },
        OrderStatus: { type: String },
        OrderType: { type: String },        
        DispatchPriority: { type: String },

        Comments: { type: Array },
        Products: { type: Array },

        Customer: { type: Object },     
        TotalDiscount: { type: Object },
        TotalShipping: { type: Object },
        TotalCoupon: { type: Object },
        TotalAmount: { type: Object },
        PaymentDetails: { type: Object },
        ClientDetails: { type: Object },

        DispatchCreatedAt: { type: String },
        DispatchUpdatedAt: { type: String },

        IsActive: { type: Boolean }
    }, 
    {
        timestamps: { 
            createdAt: 'CreatedAt', 
            updatedAt: 'UpdatedAt' 
        },
        collection: DISPATCH_ORDERS_COLLECTION
    }
);

这里我需要根据产品名称计算total Payment and total Discount。但在我的情况下,一个产品也在两个记录中出现两次。

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    在您的文档中Products 是一个数组,(可能是一个带有ProductName 字段的对象数组)当您执行"$Products.ProductName" 时,它会给您一个产品名称数组。所以$group 必须对其中包含完全相同元素的数组进行分组(即使两个数组之间的一个元素不匹配也会在小组赛阶段被视为_id 上的两个值)。所以你需要在 $group 阶段之前对 Products 数组执行 $unwind

    查询不正确:

    db.collection.aggregate([
      /** You don't need this addFields stage, just given to test, you can remove `$group` stage & check the `products` field value */
      {
        $addFields: {
          products: "$products.productName"
        }
      },
      {
        $group: {
          _id: "$products" // arrays
        }
      }
    ])
    

    测试: mongoplayground

    正确查询:

    db.collection.aggregate([
      {
        $unwind: "$products"
      },
      {
        $addFields: {
          products: "$products.productName"
        }
      },
      {
        $group: {
          _id: "$products" // Single value
        }
      }
    ])
    

    测试: mongoplayground

    参考: $unwind

    【讨论】:

    • 它工作正常,但我仍在检查像这样_id: { $ifNull: [ "$Products", false ] } 这样的对象数组中是否存在键名,这意味着它应该忽略对那些没有像$products.productName 这样的键的对象进行分组,但它也按空值分组。
    • @subhraedqart:您是否正在检查文档中是否存在 products 字段?如果是,您不必检查,因为$unwind 将删除products 不存在或为空的文档,如果您正在检查productName 字段是否存在于Products 数组的任何对象中,则将此添加为第一阶段{ $match: { "products.productName": { $exists: true } } },如果您只想保留products 数组中具有productName 字段的对象,然后在$unwind 之后添加相同的$match..
    • 这应该是一个条件。如果在Product 数组中,如果任何对象的键名是productName,则该文档只会考虑进行分组。
    • @subhraedqart :是的,您需要在$unwind 之后添加$match,正如我在之前的评论中所说的那样......
    猜你喜欢
    • 2018-09-21
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 2011-12-04
    • 1970-01-01
    相关资源
    最近更新 更多