程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何基于查找在单个聚合中执行两个 groupBy 查询大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何基于查找在单个聚合中执行两个 groupBy 查询?

开发过程中遇到如何基于查找在单个聚合中执行两个 groupBy 查询的问题如何解决?下面主要结合日常开发的经验,给出你关于如何基于查找在单个聚合中执行两个 groupBy 查询的解决方法建议,希望对你解决如何基于查找在单个聚合中执行两个 groupBy 查询有所启发或帮助;

我有两个集合,我需要使用 $lookup$group 使用单个查询对两个集合中的文档进行分组。 这是我的数据库数据和预期输出:

currentBills 表

const currentBills = [
  {
    memberID: 1,name: 'Mark',status: 'paID'
  },{
    memberID: 2,name: 'Steve',status: 'unpaID'
  },{
    memberID: 3,name: 'William',status: 'paID'
  }
];

过去的账单表格

const pastBills = [
  {
    memberID: 5,name: 'Joe',{
    memberID: 8,name: 'Carlos',{
    memberID: 25,name: 'ben',status: 'unpaID'
  }
];

预期输出


const result = {
  CurrentBill: {
    paID: [
      {
        memberID: 1,status: 'paID'
      },{
        memberID: 3,status: 'paID'
      }
    ],unpaID: [
      {
        memberID: 2,status: 'unpaID'
      }
    ]
  },pastBill: {
    paID: [
      {
        memberID: 5,{
        memberID: 8,unpaID: [
      {
        memberID: 25,status: 'unpaID'
      }
    ]
  }
};

我的查询

db.getCollection('currentBills').aggregate([
{
   $lookup:
     {
       from: "pastBills",localFIEld: "memberID",foreignFIEld: "memberID",as: "bill"
     }
},{
    $unwind : "$bill"
    },{
        $group : {
            _ID : "$status"
            }
        }
        ])

如何按 status 对每个集合进行分组并返回单个结果?这是否可以使用单个聚合查询?

提前致谢!

解决方法

演示 - https://mongoplayground.net/p/qyA1QsjfAsT

注意 - 如果您没有有限的记录集,这就是矫枉过正

db.currentBills.aggregate([
  {
    $group: { // group by status
      _id: "$status",currentBills: { $push: "$$ROOT" }
    }
  },{
    $lookup: { // add pastBills to for the status paid in paid doc and unpaid in unpaid doc
      from: "pastBills",let: { status: "$_id" },pipeline: [
        { $match: { $expr: { $eq: ["$$status","$status" ] } } }
      ],as: "pastBills"
    }
  },{
    $set: { // reshape docs with paid and unpaid keys
      currentBills: {
        $cond: [
          { $eq: [ "$_id","paid" ] },// condition
          { paid: "$currentBills" },// true
          { unpaid: "$currentBills" } // false
        ]
      },pastBills: {
        $cond: [
          { $eq: [ "$_id",{ paid: "$currentBills" },{ unpaid: "$currentBills" }
        ]
      }
    }
  },{
    $group: {
      _id: null,// group all documents
      currentBills: { $push: "$currentBills" },pastBills: { $push: "$pastBills" }
    }
  },{ $project: { _id: 0 } }
])
,

这是否可以使用单个聚合查询?

它可能在单个查询中但非常糟糕的主意,它可能会导致性能问题,如果您首先对 currentBills 进行 2 个单独的查询,然后对 pastBills 进行两个单独的查询并合并这两个结果会更好在您的编程语言中,因为这两个集合是不同的。请参阅 playground 单个集合的解决方案。

对于单个查询,您可以尝试

  • $addFields 添加 coll 字段以标识这是 currentBills 文档
  • $unionWith 联合 pastBills 文档,还 $addFields 添加 coll 字段以标识 pastBills 文档
  • $groupcollstatus 组成并构造根 @H_633_3@members 数组
  • $group 仅通过 coll 并以键值格式构造 coll 的数组
  • $group by null 并在将coll从数组转换为对象后以key-value格式构造根文档数组
  • $replaceRoot 使用 $arrayToObject
  • 将文档从数组转换为对象后替换 root 中的文档
db.currentBills.aggregate([
  { $addFields: { coll: "currentBills" } },{
    $unionWith: {
      coll: "pastBills",pipeline: [{ $addFields: { coll: "pastBills" } }]
    }
  },{
    $group: {
      _id: { coll: "$coll",status: "$status" },members: { $push: "$$ROOT" }
    }
  },{
    $group: {
      _id: "$_id.coll",coll: { $push: { k: "$_id.status",v: "$members" } }
    }
  },root: {
        $push: {
          k: "$_id",v: { $arrayToObject: "$coll" }
        }
      }
    }
  },{ $replaceRoot: { newRoot: { $arrayToObject: "$root" } } }
])

Playground


在使用此查询之前阅读此内容:

  • @H_438_9@mongoDB Limits and thresholds BSON 文档的最大大小为 16 兆字节。
  • 参见问题 How could I write aggregation without exceeds maximum document size?

大佬总结

以上是大佬教程为你收集整理的如何基于查找在单个聚合中执行两个 groupBy 查询全部内容,希望文章能够帮你解决如何基于查找在单个聚合中执行两个 groupBy 查询所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。