MongoDB嵌套聚合分组

MongoDB嵌套聚合分组,mongodb,mongodb-query,mongoose-schema,Mongodb,Mongodb Query,Mongoose Schema,样本数据: [ {type: 'partial', jobId: '121', browser: 'chrome', status:'true', jobName:'one'}, {type: 'partial', jobId: '122', browser: 'chrome', status:'false', jobName:'two'}, {type: 'partial', jobId: '121', browser: 'firefox', status:'false

样本数据:

[
    {type: 'partial', jobId: '121', browser: 'chrome', status:'true', jobName:'one'},
    {type: 'partial', jobId: '122', browser: 'chrome', status:'false', jobName:'two'},
    {type: 'partial', jobId: '121', browser: 'firefox', status:'false', jobName:'one'},
    {type: 'partial', jobId: '122', browser: 'firefox', status:'true', jobName:'two'},
    {type: 'full', jobId: '123', browser: 'chrome', status:'true', jobName:'three'},
    {type: 'full', jobId: '123', browser: 'chrome', status:'true', jobName:'three'},
    {type: 'full', jobId: '123', browser: 'chrome', status:'false', jobName:'three'},
    {type: 'full', jobId: '124', browser: 'firefox', status:'false', jobName:'four'},
]
所需产出:

[
  {
    "type": "partial",
    "browsers": [
      {
        "browser": "chrome",
        "jobIds": [
          {
            "jobId": "121",
            "results": [
              {
                "jobName": "one",
                "status": "true",
              },
            ]
          },
          {
            "jobId": "122",
            "results": [
              {
                "jobName": "two",
                "status": "false"
              },
            ]
          }
        ]
      },
      {
        "browser": "firefox",
        "testIds": [
          {
            "jobId": "121",
            "results": [
              {
                "jobName": "one",
                "status": "false"
              },
            ]
          },
          {
            "jobId": "122",
            "results": [
              {
                "jobName": "two",
                "status": "true"
              },
            ]
          }
        ]
      }
    ]
  },
  {
    "type": "full",
    "browsers": [
      {
        "browser": "chrome",
        "jobIds": [
          {
            "jobId": "123",
            "results": [
              {
                "jobName": "three",
                "status": "true"
              },
              {
                "jobName": "three",
                "status": "true"
              },
              {
                "jobName": "three",
                "status": "false"
              }
            ]
          },
        ]
      },
      {
        "browser": "firefox",
        "testIds": [
          {
            "jobId": "124",
            "results": [
              {
                "jobName": "four",
                "status": "false"
              },
            ]
          },
        ]
      }
    ]
  }
]
我知道如何使用组,但我不知道如何进行嵌套分组。我尝试了下面的查询,它没有获取所需的结果,我不知道如何继续

   db.collection.aggregate([
  {
    $match: {
      jobId: {
        "$exists": true
      }
    }
  },
  {
    $sort: {
      _id: -1
    }
  },
  {
    $group: {
      _id: {
        type: "$type",
        browser: "$browser",
        jobId: "$jobId"
      },
      results: {
        $push: {
          jobName: "$jobName",
          status: "$status",
          type: "$type",
          jobId: "$jobId"
        }
      }
    }
  },
  {
    $addFields: {
      results: {
        $slice: [
          "$results",
          30
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id.browser",
      results: {
        $push: {
          results: "$results"
        }
      }
    }
  },
  
])
需要获取最近30个结果,这就是为什么我在查询中添加了
$addFields

  • $group
    类型
    浏览器
    jobId
    进行分组并生成
    结果
    数组
  • $group
    类型
    浏览器
    和制作
    作业
    数组
  • $group
    键入
    并制作
    浏览器
    数组

你能描述一下你的预期结果和要求吗?看起来是部分还是全部,然后是每个浏览器上的浏览器,按浏览器和任务分组@turivishalpartial vs full,然后是浏览器,然后按作业分组。你只有两个浏览器,还是需要一个通用解决方案@硬代码需要一个通用的解决方案,不需要特别的两个浏览器,jobId也不需要任何特殊的东西在“jobIds”组中是否可以按“jobName”进行排序?在第二阶段中,通过对jobName进行排序,如
{$sort:{u id:-1,jobName:1},
我在第二阶段之后添加了$sort,但它无法再次检查您的playgorund,因为您在最后一个第二阶段添加了$sort stage,所以您需要添加表单第一个第二阶段的外观
db.collection.aggregate([
  { $match: { jobId: { $exists: true } } },
  { $sort: { _id: -1 } },
  {
    $group: {
      _id: {
        type: "$type",
        browser: "$browser",
        jobId: "$jobId"
      },
      results: {
        $push: {
          jobName: "$jobName",
          status: "$status"
        }
      }
    }
  },
  { $addFields: { results: { $slice: ["$results", 30] } } },
  {
    $group: {
      _id: {
        type: "$_id.type",
        browser: "$_id.browser"
      },
      browser: { $first: "$_id.browser" },
      jobIds: {
        $push: {
          jobId: "$_id.jobId",
          results: "$results"
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id.type",
      type: { $first: "$_id.type" },
      browsers: {
        $push: {
          browser: "$_id.browser",
          jobIds: "$jobIds"
        }
      }
    }
  },
  { $project: { _id: 0 } }
])