【问题标题】:MongoDB Aggregate two different groupsMongoDB 聚合两个不同的组
【发布时间】:2017-07-21 18:24:48
【问题描述】:

我有数据集,我需要该数据集中的两个不同组的值。请在下面找到数据集,

[{
    "ASSIGN_ID": "583f84bce58725f76b322398",
    "SPEC_ID": "58411772",
    "STATUS": 1,
    "UPDATE_DATE": ISODate("2016-12-21T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322398",
    "SPEC_ID": "58411772",
    "STATUS": 4,
    "UPDATE_DATE": ISODate("2016-12-22T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322398",
    "SPEC_ID": "58411772",
    "STATUS": 4,
    "UPDATE_DATE": ISODate("2016-12-23T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322398",
    "SPEC_ID": "58411774",
    "STATUS": 3,
    "UPDATE_DATE": ISODate("2016-12-24T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322311",
    "SPEC_ID": "58411775",
    "STATUS": 1,
    "UPDATE_DATE": ISODate("2016-12-25T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322311",
    "SPEC_ID": "58411775",
    "STATUS": 3,
    "UPDATE_DATE": ISODate("2016-12-23T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322322",
    "SPEC_ID": "58411774",
    "STATUS": 1,
    "UPDATE_DATE": ISODate("2016-12-20T04:10:23.000Z")
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322322",
    "SPEC_ID": "58411778",
    "STATUS": 4,
    "UPDATE_DATE": ISODate("2016-12-21T04:10:23.000Z")
  }
]

我想通过使用 ASSIGN_ID 和 STATUS 以及在我需要的每个 ASSIGN_ID 组内进行分组 SPEC_ID以及STATUS。请在下面找到预期的输出,

[{
    "ASSIGN_ID": "583f84bce58725f76b322398",
    "ASSIGN_GROUP": [{
        "STATUS": 1,
        "COUNT": 1
      },
      {
        "STATUS": 3,
        "COUNT": 1
      },
      {
        "STATUS": 4,
        "COUNT": 2
      }
    ],
    "SPEC_ARRAY": [{
        "SPEC_ID": "58411772",
        "SPEC_GROUP": [{
            "STATUS": 1,
            "COUNT": 1
          },
          {
            "STATUS": 4,
            "COUNT": 2
          }
        ]
      },
      {
        "SPEC_ID": "58411774",
        "SPEC_GROUP": [{
          "STATUS": 3,
          "COUNT": 1
        }]
      }
    ]
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322311",
    "ASSIGN_GROUP": [{
        "STATUS": 1,
        "COUNT": 1
      },
      {
        "STATUS": 3,
        "COUNT": 1
      }
    ],
    "SPEC_ARRAY": [{
      "SPEC_ID": "58411775",
      "SPEC_GROUP": [{
          "STATUS": 1,
          "COUNT": 1
        },
        {
          "STATUS": 3,
          "COUNT": 1
        }
      ]
    }]
  },
  {
    "ASSIGN_ID": "583f84bce58725f76b322322",
    "ASSIGN_GROUP": [{
        "STATUS": 1,
        "COUNT": 1
      },
      {
        "STATUS": 4,
        "COUNT": 1
      }
    ],
    "SPEC_ARRAY": [{
        "SPEC_ID": "58411774",
        "SPEC_GROUP": [{
          "STATUS": 1,
          "COUNT": 1
        }]
      },
      {
        "SPEC_ID": "58411778",
        "SPEC_GROUP": [{
          "STATUS": 4,
          "COUNT": 1
        }]
      }
    ]
  }
]

目前,我到目前为止所做的只是将 ASSIGN_ID 分组并按 STATUS 请在下面找到代码,

Modal.aggregate([
  {
    "$group": {
      "_id": {
        "INSPECTED_BY": "$INSPECTED_BY",
        "STATUS": "$STATUS"
      },
      "spec_id": "$SPEC_ID",
      "total": {
        "$sum": 1
      }
    }
  }, {
    "$group": {
      "_id": "$_id.INSPECTED_BY",
      "data": {
        "$push": {
          "STATUS": "$_id.STATUS",
          "total": "$total"
        }
      }
    }
  }
]);

结果是

[
  {
    "_id": "583f84bce58725f76b322398",
    "data": [
      {
        "STATUS": 1,
        "COUNT": 1
      }, {
        "STATUS": 3,
        "COUNT": 1
      }, {
        "STATUS": 4,
        "COUNT": 2
      }
    ]
  }, {
    "_id": "583f84bce58725f76b322311",
    "data": [
      {
        "STATUS": 1,
        "COUNT": 1
      }, {
        "STATUS": 3,
        "COUNT": 1
      }
    ]
  }, {
    "_id": "583f84bce58725f76b322322",
    "data": [
      {
        "STATUS": 1,
        "COUNT": 1
      }, {
        "STATUS": 4,
        "COUNT": 1
      }
    ]
  }
]

请给我一个合适的解决方案以获得预期的结果。

【问题讨论】:

  • 你的 mongo 服务器版本是多少?
  • 版本是:3.2.1

标签: javascript node.js mongodb mongoose aggregation-framework


【解决方案1】:

这是一个多通道管道;如果需要在同一通道中获取两组不同的分组;必须先分组一组。到达该组后,保留下一组分组所需的数据。

涉及的管道:
group :(1) 按 ASSIGN_ID、SPEC_ID、STATUS 分组 - 获取此组合的计数
group :(2) 按 ASSIGN_ID、SPEC_ID 分组 - 准备 SPEC_GROUP 数组group :(3) 按 ASSIGN_ID 分组 - 准备 SPEC_ARRAY 对象数组
project : 选择 ASSIGN_ID、SPEC_ARRAY、SPEC_ARRAY 数据的副本以准备按状态分组
unwind : 展开 SPEC 数组元素来获取每个 spec_id 分隔的数据
unwind :展开 SPEC 数组。 SPEC_GROUP 元素用于获取每个 spec_id /status 分隔的数据
group :(4) 按 ASSIGN_ID,STATUS 分组 - 获取每个状态的计数 [获取计数时添加与每个状态相对应的计数,因为我们已经按 SPEC_ID 分组] ,从第一行中选择 SPEC_ARRAY,因为它在整个重复
group :(5) 按 ASSIGN_ID 分组 - 获取分配组数组,从第一行中选择 SPEC_ARRAY,因为它在整个重复

db.Modal.aggregate([ {
    $group : {
        _id : {
            ASSIGN_ID : "$ASSIGN_ID",
            SPEC_ID : "$SPEC_ID",
            STATUS : "$STATUS"
        },
        a_s_cnt : {
            $sum : 1
        }
    }
}, {
    $group : {
        _id : {
            ASSIGN_ID : "$_id.ASSIGN_ID",
            SPEC_ID : "$_id.SPEC_ID"
        },
        SPEC_GROUP : {
            $push : {
                STATUS : "$_id.STATUS",
                COUNT : "$a_s_cnt"
            }
        }
    }
}, {
    $group : {
        _id : "$_id.ASSIGN_ID",
        SPEC_ARRAY : {
            $push : {
                SPEC_ID : "$_id.SPEC_ID",
                SPEC_GROUP : "$SPEC_GROUP"
            }
        }
    }
}, {
    $project : {
        _id : 0,
        ASSIGN_ID : "$_id",
        SPEC_ARRAY : "$SPEC_ARRAY",
        forStatus : "$SPEC_ARRAY"
    }
}, {
    $unwind : "$forStatus"
}, {
    $unwind : "$forStatus.SPEC_GROUP"
}, {
    $group : {
        _id : {
            ASSIGN_ID : "$ASSIGN_ID",
            STATUS : "$forStatus.SPEC_GROUP.STATUS"
        },
        statusCount : {
            $sum : "$forStatus.SPEC_GROUP.COUNT"
        },
        SPEC_ARRAY : {
            $first : "$SPEC_ARRAY"
        }
    }
}, {
    $group : {
        _id : "$_id.ASSIGN_ID",
        ASSIGN_GROUP : {
            $push : {
                STATUS : "$_id.STATUS",
                COUNT : "$statusCount"
            }
        },
        SPEC_ARRAY : {
            $first : "$SPEC_ARRAY"
        }
    }
}, {
    $project : {
        _id : 0,
        ASSIGN_ID : "$_id",
        ASSIGN_GROUP : "$ASSIGN_GROUP",
        SPEC_ARRAY : "$SPEC_ARRAY"
    }
} ])

【讨论】:

    【解决方案2】:

    您可以尝试以下版本 3.2 的替代聚合。

    Modal.aggregate([{
        $group: {
            _id: {
                ASSIGN_ID: "$ASSIGN_ID",
                SPEC_ID: "$SPEC_ID",
                STATUS: "$STATUS"
            },
            COUNT: {
                $sum: 1
            }
        }
    }, {
        $group: {
            _id: {
                ASSIGN_ID: "$_id.ASSIGN_ID",
                SPEC_ID: "$_id.SPEC_ID"
            },
            SPEC_GROUP: {
                $push: {
                    STATUS: "$_id.STATUS",
                    COUNT: "$COUNT"
                }
            }
        }
    }, {
        $group: {
            _id: "$_id.ASSIGN_ID",
            SPEC_ARRAY: {
                $push: {
                    SPEC_ID: "$_id.SPEC_ID",
                    SPEC_GROUP: "$SPEC_GROUP"
                }
            }
        }
    }, {
        $project: {
            ASSIGN_ID: "$_id",
            ASSIGN_GROUP: "$SPEC_ARRAY.SPEC_GROUP",
            SPEC_ARRAY: 1
        }
    }, {
        $unwind: "$ASSIGN_GROUP"
    }, {
        $unwind: "$ASSIGN_GROUP"
    }, {
        $group: {
            _id: "$ASSIGN_ID",
            ASSIGN_GROUP: {
                $push: "$ASSIGN_GROUP"
            },
            SPEC_ARRAY: {
                $first: "$SPEC_ARRAY"
            }
        }
    }])
    

    将最后四个阶段替换为$reducefor 3.4 版

    {
        $project: {
            _id: 0,
            ASSIGN_ID: "$_id",
            SPEC_ARRAY: 1,
            ASSIGN_GROUP: {
                $reduce: {
                    input: "$SPEC_ARRAY.SPEC_GROUP",
                    initialValue: [],
                    in: {
                        $concatArrays: ["$$value", "$$this"]
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      使用此聚合命令,使用您的示例数据进行测试,

              db.test.aggregate([{
          $group: {
              _id: {
                  ASSIGN_ID: "$ASSIGN_ID",
                  STATUS: "$STATUS",
                  SPEC_ID: "$SPEC_ID"
              },
              count: {
                  "$sum": 1
              }
          }
      }, {
          $group: {
              _id: "$_id.ASSIGN_ID",
              ASSIGN_GROUP: {
                  $push: {
                      STATUS: "$_id.STATUS",
                      count: "$count"
                  }
              },
              SPEC_ARRAY: {
                  $push: {
                      SPEC_ID: "$_id.SPEC_ID",
                      STATUS: "$_id.STATUS",
                      count: "$count"
                  }
              }
          }
      }, {
          $unwind: "$SPEC_ARRAY"
      }, {
          $group: {
              _id: {
                  ASSIGN_ID: "$_id",
                  SPEC_ID: "$SPEC_ARRAY.SPEC_ID"
              },
              ASSIGN_GROUP: {
                  $first: "$ASSIGN_GROUP"
              },
              SPEC_GROUP: {
                  $push: {
                      "STATUS": "$SPEC_ARRAY.STATUS",
                      count: "$SPEC_ARRAY.count"
                  }
              }
          }
      }, {
          $group: {
              _id: "$_id.ASSIGN_ID",
              ASSIGN_GROUP: {
                  $first: "$ASSIGN_GROUP"
              },
              SPEC_ARRAY: {
                  $push: {
                      SPEC_ID: "$_id.SPEC_ID",
                      SPEC_GROUP: "$SPEC_GROUP"
                  }
              }
          }
      }
      
      ]).pretty()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-13
        • 2015-07-26
        • 2013-04-28
        • 1970-01-01
        • 2018-05-25
        相关资源
        最近更新 更多