首页 > 解决方案 > 使用聚合查询获取具有总交易计数和交易详细信息的用户列表作为嵌入文档

问题描述

我正在尝试获取具有总事务计数的用户列表,并且每个用户都应该使用 MongoDB 的聚合管道在 GET API 中获取结果作为嵌入对象的最新事务详细信息。

我有以下数据库架构:

用户:_id、姓名、电话、地址

产品:_id、名称、unit_price、描述

交易:_id, date, product_id(ref to Product), user_id(ref to User), quantity, total_price


预期响应 JSON

[
    {
        name:"",
        phone:"",
        address:"",
        total_transaction:
        latest_transaction_detail: {
            product_id:
            quantity:
            total_price:                                                        
        }
    },
    {
        name:"",
        phone:"",
        address:"",
        total_transaction:
        latest_transaction_detail: {
            product_id:
            quantity:
            total_price:                                                        
        }
    }
]

如何生成聚合查询以返回上述内容?

标签: node.jsmongodbmongooseaggregation-framework

解决方案


您可以通过运行聚合查询来实现此目的。

  • 查找阶段会将您的 User 集合与您的 Transaction 集合加入(无需在您的预期结果中加入 Product)。它的管道被 $facet 分割,用于获取该用户的计数结果和最新交易

  • 项目阶段将重塑您的数据并将数组元素提取到文档中。

这是一个这样的查询:

db.User.aggregate(
[
    {
        $lookup: 
         {
            from: "Transaction",
           let: { userId: "$_id" },
            pipeline: [ 
            {$facet:
              {count:[{$match:{$expr:{$eq:["$$userId","$user_id"]}}}, {$count:"total_transaction"}],
                latest:[
                {$match:{$expr:{$eq:["$$userId","$user_id"]}}},
                {$sort:{date:-1}},
                {$limit:1}]
            } }],
            as: "transactions"
         }
    },
    {
        $project: {
          last_name:1,
          phone:1,
          address:1,
            total_transaction : {
              $let:{
                vars:{
                  count:{
                    $arrayElemAt:["$transactions.count",0]
                    }
                  },
                in:{
                  $arrayElemAt:["$$count.total_transaction",0]
                  }
                }
              },
              latest_transaction : {
              $let:{
                vars:{
                  latest:{
                    $arrayElemAt:["$transactions.latest",0]
                    }
                  },
                in:{
                  $arrayElemAt:["$$latest",0]
                  }
                }


              },    
            }
        },
    ]
);

推荐阅读