如何优化聚合查询以根据不同的键进行分组?
How to optimise aggregation query to group based on different keys?
我的 mongoDB 文档如下所示:
[
{
"fields": {
"field_1": {
"name": "f1",
"first": {
"check": true
}
},
"field_2": {
"name": "f2",
"second": {
"check": true
}
},
"field_3": {},
"field_4": {
"name": "f4",
"second": {
"check": true
}
}
}
},
{
"fields": {
"field_1": {
"name": "f1",
"second": {
"check": false
}
},
"field_2": {
"name": "f2",
"second": {
"check": true
},
"first": {
"check": true
}
},
"field_3": {
"name": "f3",
"second": {
"check": true
}
}
}
}
]
预期输出:
创建父组 f1(fields.field1.name
) 和 f2(fields.field2.name
)
他们每个人都有两个子组,这些子组根据以下条件显示指标
各自父组:
- first_group:
first.check=true
的文档数
- second_group:
first.check
不存在且 second.check=true
的文档数
结果:
[
{
"data": [
{
"_id": "f1",
"values": [
{
"second_group": 0,
"first_group": 1
}
]
},
{
"_id": "f2",
"values": [
{
"second_group": 1,
"first_group": 1
}
]
}
]
}
]
我已经使用 $facet 生成了查询,但我不满意,因为我必须在每个父组中重复我的子级分组逻辑(我在 $facet 中有 4 个数组)
My Query in Mongo Playground attached here
请告诉我如何删除重复查询。
有没有其他方法可以实现这个用例?
谢谢!
发布应该适用于给定条件和预期的聚合查询 O/p:
db.collection.aggregate([
{
$unwind: "$fields",
},
{
$project: {
data: {
$objectToArray: "$fields",
},
},
},
{
$unwind: "$data",
},
{
$match: {
"data.v.first.check": true,
},
},
{
$group: {
_id: "$data.v.name",
values: {
$push: {
first_group: {
$sum: {
$cond: [
{
$eq: ["$data.v.first.check", true],
},
1,
0,
],
},
},
second_group: {
$sum: {
$cond: [
{
$eq: ["$data.v.second.check", true],
},
1,
0,
],
},
},
},
},
},
},
]);
备选方案:
我们标准化 fields
属性并使用 $convert operator to Integer
with this behavior.
计算 first_group
和 second_group
值
Input Type Behavior
---------------------
Boolean Returns 0 for false.
Returns 1 for true.
db.collection.aggregate([
{
$project: {
fields: {
$map: {
input: [
"$fields.field_1",
"$fields.field_2"
],
as: "field",
in: {
_id: "$$field.name",
first_group: {
$convert: {
input: "$$field.first.check",
to: 16,
onNull: 0
}
},
second_group: {
$convert: {
input: {
$and: [
{
$eq: [
{
$type: "$$field.first.check"
},
"missing"
]
},
"$$field.second.check"
]
},
to: 16,
onNull: 0
}
}
}
}
}
}
},
{
$unwind: "$fields"
},
{
$group: {
_id: "$fields._id",
first_group: {
$sum: "$fields.first_group"
},
second_group: {
$sum: "$fields.second_group"
}
}
},
{
$group: {
_id: null,
data: {
$push: {
_id: "$_id",
values: [
{
first_group: "$first_group",
second_group: "$second_group"
}
]
}
}
}
}
])
我的 mongoDB 文档如下所示:
[
{
"fields": {
"field_1": {
"name": "f1",
"first": {
"check": true
}
},
"field_2": {
"name": "f2",
"second": {
"check": true
}
},
"field_3": {},
"field_4": {
"name": "f4",
"second": {
"check": true
}
}
}
},
{
"fields": {
"field_1": {
"name": "f1",
"second": {
"check": false
}
},
"field_2": {
"name": "f2",
"second": {
"check": true
},
"first": {
"check": true
}
},
"field_3": {
"name": "f3",
"second": {
"check": true
}
}
}
}
]
预期输出:
创建父组 f1(
fields.field1.name
) 和 f2(fields.field2.name
)他们每个人都有两个子组,这些子组根据以下条件显示指标 各自父组:
- first_group:
first.check=true
的文档数
- second_group:
first.check
不存在且second.check=true
的文档数
- first_group:
结果:
[
{
"data": [
{
"_id": "f1",
"values": [
{
"second_group": 0,
"first_group": 1
}
]
},
{
"_id": "f2",
"values": [
{
"second_group": 1,
"first_group": 1
}
]
}
]
}
]
我已经使用 $facet 生成了查询,但我不满意,因为我必须在每个父组中重复我的子级分组逻辑(我在 $facet 中有 4 个数组)
My Query in Mongo Playground attached here
请告诉我如何删除重复查询。 有没有其他方法可以实现这个用例?
谢谢!
发布应该适用于给定条件和预期的聚合查询 O/p:
db.collection.aggregate([
{
$unwind: "$fields",
},
{
$project: {
data: {
$objectToArray: "$fields",
},
},
},
{
$unwind: "$data",
},
{
$match: {
"data.v.first.check": true,
},
},
{
$group: {
_id: "$data.v.name",
values: {
$push: {
first_group: {
$sum: {
$cond: [
{
$eq: ["$data.v.first.check", true],
},
1,
0,
],
},
},
second_group: {
$sum: {
$cond: [
{
$eq: ["$data.v.second.check", true],
},
1,
0,
],
},
},
},
},
},
},
]);
备选方案:
我们标准化 fields
属性并使用 $convert operator to Integer
with this behavior.
first_group
和 second_group
值
Input Type Behavior
---------------------
Boolean Returns 0 for false.
Returns 1 for true.
db.collection.aggregate([
{
$project: {
fields: {
$map: {
input: [
"$fields.field_1",
"$fields.field_2"
],
as: "field",
in: {
_id: "$$field.name",
first_group: {
$convert: {
input: "$$field.first.check",
to: 16,
onNull: 0
}
},
second_group: {
$convert: {
input: {
$and: [
{
$eq: [
{
$type: "$$field.first.check"
},
"missing"
]
},
"$$field.second.check"
]
},
to: 16,
onNull: 0
}
}
}
}
}
}
},
{
$unwind: "$fields"
},
{
$group: {
_id: "$fields._id",
first_group: {
$sum: "$fields.first_group"
},
second_group: {
$sum: "$fields.second_group"
}
}
},
{
$group: {
_id: null,
data: {
$push: {
_id: "$_id",
values: [
{
first_group: "$first_group",
second_group: "$second_group"
}
]
}
}
}
}
])