Mongo 嵌套数组分组,保留原始数据聚合框架
Mongo group by nested array, preserving original data Aggregation Framework
我有以下架构,我在 JS 中使用带有 mongoose 的聚合框架
{
id: 1,
name: Alfred,
age: 10,
orders:[
{type:"A",address:"Address1"},
{type:"A",address:"Address2"},
{type:"B",address:"Address4"},
{type:"B",address:"Address5"},
{type:"B",address:"Address6"},
...
]
},
{
id: 2,
name: Bren,
age: 15,
orders:[
{type:"B",address:"Address1"},
{type:"B",address:"Address2"},
{type:"B",address:"Address4"},
{type:"A",address:"Address5"},
{type:"B",address:"Address6"},
...
]
}
我正在尝试获取此输出
{
id: 1,
name: Alfred,
age:10,
countTypeA:2,
countTypeB:3
},
{
id: 2
name: Bren,
age: 15,
countTypeA: 1,
countTypeB: 4
}
我试过使用 $unwind
和 $group:{_id:"orders.type"}
但我丢失了每一行的原始数据(姓名、年龄),我不介意丢失地址信息,我'我有兴趣计算每个用户在其订单列表中的订单类型。
$unwind
- 将 orders
数组解构为多个文档。
$group
- 按 id
和 orders.type
分组。并通过 $first
. 存储其他属性
$group
- 按 id
分组。通过 $first
存储其他属性。并使用 key-value 对文档创建 type
数组。
$replaceRoot
- 用所需文档替换输入文档。
$unset
- 删除 type
字段。
db.collection.aggregate([
{
$unwind: "$orders"
},
{
$group: {
_id: {
id: "$id",
type: "$orders.type"
},
name: {
$first: "$name"
},
age: {
$first: "$age"
},
count: {
$sum: 1
}
}
},
{
$group: {
_id: "$_id.id",
name: {
$first: "$name"
},
age: {
$first: "$age"
},
type: {
$push: {
k: {
$concat: [
"countType",
"$_id.type"
]
},
v: "$count"
}
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$$ROOT",
{
"$arrayToObject": "$type"
}
]
}
}
},
{
$unset: "type"
}
])
我有以下架构,我在 JS 中使用带有 mongoose 的聚合框架
{
id: 1,
name: Alfred,
age: 10,
orders:[
{type:"A",address:"Address1"},
{type:"A",address:"Address2"},
{type:"B",address:"Address4"},
{type:"B",address:"Address5"},
{type:"B",address:"Address6"},
...
]
},
{
id: 2,
name: Bren,
age: 15,
orders:[
{type:"B",address:"Address1"},
{type:"B",address:"Address2"},
{type:"B",address:"Address4"},
{type:"A",address:"Address5"},
{type:"B",address:"Address6"},
...
]
}
我正在尝试获取此输出
{
id: 1,
name: Alfred,
age:10,
countTypeA:2,
countTypeB:3
},
{
id: 2
name: Bren,
age: 15,
countTypeA: 1,
countTypeB: 4
}
我试过使用 $unwind
和 $group:{_id:"orders.type"}
但我丢失了每一行的原始数据(姓名、年龄),我不介意丢失地址信息,我'我有兴趣计算每个用户在其订单列表中的订单类型。
$unwind
- 将orders
数组解构为多个文档。$group
- 按id
和orders.type
分组。并通过$first
. 存储其他属性
$group
- 按id
分组。通过$first
存储其他属性。并使用 key-value 对文档创建type
数组。$replaceRoot
- 用所需文档替换输入文档。$unset
- 删除type
字段。
db.collection.aggregate([
{
$unwind: "$orders"
},
{
$group: {
_id: {
id: "$id",
type: "$orders.type"
},
name: {
$first: "$name"
},
age: {
$first: "$age"
},
count: {
$sum: 1
}
}
},
{
$group: {
_id: "$_id.id",
name: {
$first: "$name"
},
age: {
$first: "$age"
},
type: {
$push: {
k: {
$concat: [
"countType",
"$_id.type"
]
},
v: "$count"
}
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$$ROOT",
{
"$arrayToObject": "$type"
}
]
}
}
},
{
$unset: "type"
}
])