根据 MongoDB 中的不同字段汇总结果

Aggregate results based on different fields in MongoDB

我正在尝试在单个查询中为同一集合中的所有所有者获取位置明智数据和预算明智数据的计数。将来我们可能还需要显示基于项目的报告。 以下是示例合集。

[
  {
    "owner": 1,
    "location": "Goa",
    "budget": "1 Cr and Above",
    "project": "ABC"
  },
  {
    "owner": 1,
    "location": "Goa",
    "budget": "10 - 30 Lacs",
    "project": "ABC"
  },
  {
    "owner": 1,
    "location": "Mumbai",
    "budget": "30 - 50 Lacs",
    "project": "XYZ"
  },
  {
    "owner": 2,
    "location": "Delhi",
    "budget": "30 - 50 Lacs",
    "project": "ABC"
  },
  {
    "owner": 2,
    "location": "Delhi",
    "budget": "1 Cr and Above",
    "project": "DEF"
  },
  {
    "owner": 2,
    "location": "Delhi",
    "budget": "30 - 50 Lacs",
    "project": "ABC"
  },
  {
    "owner": 3,
    "location": "Goa",
    "budget": "70 - 90 Lacs",
    "project": "DEF"
  },
  {
    "owner": 3,
    "location": "Mumbai",
    "budget": "70 - 90 Lacs",
    "project": "XYZ"
  },
  {
    "owner": 4,
    "location": "Bangalore",
    "budget": "2 Cr and Above",
    "project": "DEF"
  },
  {
    "owner": 4,
    "location": "Goa",
    "budget": "2 Cr and Above",
    "project": "ABC"
  }
]

以下是我为获取所有者的位置明智记录而执行的查询:

db.collection.aggregate([
  {
    "$group": {
      "_id": {
        "owner": "$owner",
        "location": "$location",
        "budget": "$budget"
      },
      "num": {
        "$sum": 1
      }
    }
  },
  {
    "$group": {
      "_id": "$_id.owner",
      "location": {
        "$push": {
          "location": "$_id.location",
          "count": "$num"
        }
      }
    }
  },
  {
    "$project": {
      "owner": "$_id",
      "_id": false,
      "location": 1,
      "totalLocation": {
        "$sum": "$location.count"
      },
      "totalBudget": {
        "$sum": "$budget.count"
      }
    }
  }
])

输出如下。

[
  {
    "location": [
      {
        "count": 1,
        "location": "Goa"
      },
      {
        "count": 1,
        "location": "Bangalore"
      }
    ],
    "owner": 4,
    "totalLocation": 2
  },
  {
    "location": [
      {
        "count": 3,
        "location": "Delhi"
      }
    ],
    "owner": 2,
    "totalLocation": 3
  },
  {
    "location": [
      {
        "count": 1,
        "location": "Mumbai"
      },
      {
        "count": 2,
        "location": "Goa"
      }
    ],
    "owner": 1,
    "totalLocation": 3
  },
  {
    "location": [
      {
        "count": 1,
        "location": "Goa"
      },
      {
        "count": 1,
        "location": "Mumbai"
      }
    ],
    "owner": 3,
    "totalLocation": 2
  }
]

我应该如何修改相同的查询以在相同的结果集中获得预算明智的数据?如下所示。

[
  {
    "location": [
      {
        "count": 1,
        "location": "Goa"
      },
      {
        "count": 1,
        "location": "Bangalore"
      }
    ],
    "budget": [
      {
        "count": 2,
        "budget": "2 Cr and Above"
      }
    ],
    "owner": 4,
    "totalLocation": 2,
    "totalBudget": 2,
  },
  {
    "location": [
      {
        "count": 3,
        "location": "Delhi"
      }
    ],
    "budget": [
      {
        "count": 2,
        "budget": "30 - 50 Lacs"
      },
      {
        "count": 1,
        "budget": "1 Cr and Above"
      }
    ],
    "owner": 2,
    "totalLocation": 3,
    "totalBudget": 2
  },
  {
    "location": [
      {
        "count": 1,
        "location": "Mumbai"
      },
      {
        "count": 2,
        "location": "Goa"
      }
    ],
    "budget": [
      {
        "count": 1,
        "budget": "1 Cr and Above"
      },
      {
        "count": 1,
        "budget": "10 - 30 Lacs"
      },
      {
        "count": 1,
        "budget": "30 - 50 Lacs"
      }
    ],
    "owner": 1,
    "totalLocation": 3,
    "totalBudget": 3
  },
  {
    "location": [
      {
        "count": 1,
        "location": "Goa"
      },
      {
        "count": 1,
        "location": "Mumbai"
      }
    ],
    "budget": [
      {
        "count": 1,
        "budget": "70 - 90 Lacs"
      }
    ],
    "owner": 3,
    "totalLocation": 2,
    "totalBudget": 1
  }
]

编辑:

在这种情况下,我会编辑我的原始回复并建议:

db.collection.aggregate([
  {
    $facet: {
      budgets: [
        {
          "$group": {
            "_id": {
              "owner": "$owner",
              "budget": "$budget"
            },
            budgetCount: {$sum: 1}
          }
        },
        {
          "$group": {
            "_id": {"owner": "$_id.owner"},
            budgets: {
              "$addToSet": {
                budget: "$_id.budget",
                count: "$budgetCount"
              }
            },
            totalBudgets: {$sum: "$budgetCount"},
          }
        },
        {
          $project: {
            owner: "$_id.owner",
            _id: 0,
            budgets: 1,
            totalBudgets: 1,
            locations: null,
            projects: null
          }
        }
      ],
      locations: [
        {
          "$group": {
            "_id": {
              "owner": "$owner",
              "location": "$location"
            },
            locationsCount: {$sum: 1}
          }
        },
        {
          "$group": {
            "_id": {"owner": "$_id.owner"},
            locations: {
              "$addToSet": {
                location: "$_id.location",
                count: "$budgetCount"
              }
            },
            totalLocations: {$sum: "$locationsCount"},
          }
        },
        {
          $project: {
            owner: "$_id.owner",
            _id: 0,
            locations: 1,
            totalLocations: 1,
            budgets: null,
            projects: null
          }
        }
      ],
      projects: [
        {
          "$group": {
            "_id": {
              "owner": "$owner",
              "project": "$project"
            },
            projectsCount: {$sum: 1}
          }
        },
        {
          "$group": {
            "_id": {"owner": "$_id.owner"},
            projects: {
              "$addToSet": {
                project: "$_id.project",
                count: "$projectsCount"
              }
            },
            totalProjects: {$sum: "$projectsCount"},
          }
        },
        {
          $project: {
            owner: "$_id.owner",
            _id: 0,
            projects: 1,
            totalProjects: 1,
            budgets: null,
            locations: null
          }
        }
      ],
    }
  },
  {
    $project: {
      data: {
        "$concatArrays": [
          "$budgets",
          "$locations",
          "$projects"
        ]
      }
    }
  },
  {
    $unwind: "$data"
  },
  {
    $group: {
      _id: "$data.owner",
      locations: {
        $push: {
          $ifNull: ["$data.locations", "$$REMOVE"]
        }
      },
      budgets: {
        $push: {
          $ifNull: ["$data.budgets", "$$REMOVE"]
        }
      },
      projects: {
        $push: {
          $ifNull: ["$data.projects", "$$REMOVE"]
        }
      },
      totalBudgets: {$sum: "$data.totalBudgets"},
      totalLocations: {$sum: "$data.totalLocations"},
      totalProjects: {$sum: "$data.totalProjects"},   
    }
  },
  {
    "$project": {
      "_id": 0,
      "owner": "$_id",
      "locations": {"$arrayElemAt": ["$locations", 0]},
      "projects": {"$arrayElemAt": ["$projects", 0]},
      "budget": {"$arrayElemAt": ["$budgets", 0]},
      totalBudgets: 1,
      totalLocations: 1,
      totalProjects: 1
    }
  }
])

为了演示功能,您可以看到 here 输入数据稍有变化。