0

次のようなコレクションがあるとします。

{
  "_id": "10280",
  "city": "NEW YORK",
  "state": "NY",
  "departments": [
             {"departmentType":"01",
              "departmentHead":"Peter"},
             {"departmentType":"02",
              "departmentHead":"John"}
  ]
},
{
  "_id": "10281",
  "city": "LOS ANGELES",
  "state": "CA",
  "departments": [
             {"departmentType":"02",
              "departmentHead":"Joan"},
             {"departmentType":"03",
              "departmentHead":"Mary"}
  ]
},
{
  "_id": "10284",
  "city": "MIAMI",
  "state": "FL",
  "department": [
  "departments": [
             {"departmentType":"01",
              "departmentHead":"George"},
             {"departmentType":"02",
              "departmentHead":"Harry"}
  ]
}

次のように、departmentType ごとにカウントを取得したいと思います。

[{"departmentType":"01", "dCount":2},
 {"departmentType":"02", "dCount":3},
 {"departmentType":"03", "dCount":1}
]

このために、私はすでにほとんどすべてを試しましたが、オンラインで見つけたすべての例は、グループ化がドキュメントのルート レベルのフィールドに対して行われる簡単なものです。代わりに、ここでは departmentType でグループ化しようとしていますが、これまでに見つけたすべてのものを壊しているようです。

Mongoose の集計実装または mapreduce を使用してこれを行う方法についてのアイデアはありますか?

理想的には、count <= 1 のすべての departmentTypes を除外し、結果を departmentType で並べ替えたいと考えています。

よろしくお願いします!

4

1 に答える 1

0

パイプラインでそれらを集約できるように、配列内の各エントリのドキュメントを作成する departments 配列を $unwind する必要があります。

残念ながら、$size は正確な値しかとらないため、departmentTypes <= 1 を事前にフィルター処理することはできませんが、結果から除外することはできます。それは素晴らしいことではありませんが、うまくいきます。この例では、正確に 2 つの部門を持つレコードのみを事前にフィルター処理していますが、これはデモ専用です。後で結果の 2 番目の $match で <=1 を除外するため、おそらく最初の $match を削除することをお勧めします。

db.runCommand({
    aggregate: "so",
    pipeline: [
        {   // filter out only records with 2 departments
            $match: {
                departments: { $size: 2 }
            }
        },
        // unwind - create a doc for each department in the array
        { $unwind: "$departments" },
        {   // aggregate sum of departments by type
            $group: {
                _id: "$departments.departmentType",
                count: { $sum: 1 },
            }
        },
        {   // filter out departments with <=1
            $match: {
                count: { $gt: 1 },
            }
        },
        {   // rename fields as per example
            $project: {
                _id: 0,
                departmentType: "$_id",
                dCount: "$count",
            }
        }
    ]
});

また、以前の json サンプルにはタイプミスがあり、「部門」は実際には存在しないと想定していることに注意してください。このコードは、すべてのドキュメントが最初の 2 つと同じスキーマを持っていると仮定して機能します。

取得する実際のフィールド名が気にならない場合は、最初の $match と最後の $project を自由に削除してください。

于 2012-10-05T21:22:03.717 に答える