使用聚合查询获取具有总交易数和交易明细的用户列表作为嵌入式文档

时间:2018-10-03 10:52:10

标签: node.js mongodb mongoose aggregation-framework

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

我具有以下数据库架构:

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

产品:_ id,名称,单价,说明

交易:_id,日期,product_id(参考产品),user_id(参考用户),数量,总价


期望的响应JSON

Map<String,List<String>> groupByIP = 
    array_ip.stream()
            .collect(Collectors.groupingBy(class_ip::getIP,
                                           Collectors.mapping(class_ip::getTitle,
                                                              Collectors.toList())));

如何生成汇总查询以返回以上内容?

1 个答案:

答案 0 :(得分:0)

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

  • 一个查找阶段会将您的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]
                  }
                }


              },    
            }
        },
    ]
);