大佬教程收集整理的这篇文章主要介绍了如何基于查找在单个聚合中执行两个 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
文档$group
由 coll
和 status
组成并构造根 @H_633_3@members 数组$group
仅通过 coll
并以键值格式构造 coll
的数组$group
by null 并在将coll从数组转换为对象后以key-value格式构造根文档数组$replaceRoot
使用 $arrayToObject
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
在使用此查询之前阅读此内容:
以上是大佬教程为你收集整理的如何基于查找在单个聚合中执行两个 groupBy 查询全部内容,希望文章能够帮你解决如何基于查找在单个聚合中执行两个 groupBy 查询所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。