2017-02-06 2 views
0

特定のフィールドのコレクション内のドキュメントをグループ化し、各グループの出力結果については、次を含めることを検討しています。

  1. (いくつかの表現{「$プロパティ」:「価値」}満たす文書のつまりcount)特定のクエリに一致するグループ内のすべての文書の数
  2. グループ内のドキュメントの合計数
  3. (これは簡単には実現しないと思われるので、ボーナス)$ min/$ maxアキュムレータに対応する文書のプロパティ

私はmongoでのクエリに使用されている構文に非常に新しいので、すべての仕組みを理解していませんが、いくつかの調査の後で、次のクエリを取得できました。私は現在、私のmongo DBのバージョン3.0.12を使用していますが、私たちは数ヶ月時間)にアップグレードします信じている:

db.getCollection('myCollection').aggregate(
    [ 
     { 
      $group: { 
       _id: { 
        GroupID: "$GroupID", 
        Status: "$Status" 
       }, 
       total: { $sum: 1 }, 
       GroupName: { $first: "$GroupName" }, 
       EarliestCreatedDate: { $min: "$DateCreated" }, 
       LastModifiedDate: { $max: "$LastModifiedDate" } 
      } 
     }, 
     { 
      $group: { 
       _id: "$_id.GroupID", 
       Statuses: { 
        $push: { 
         Status: "$_id.Status", 
         Count: "$total" 
        } 
       }, 
       TotalCount: { $sum: "$total" }, 
       GroupName: { $first: "$GroupName" }, 
       EarliestCreatedDate: { $min: "$EarliestCreatedDate" }, 
       LastModifiedDate: { $max: "$LastModifiedDate" } 
      } 
     } 
    ] 
) 

基本的に私は何を取得するために探していますが、特定のステータス値のカウントであり、それらを次のような最終結果ドキュメントに投影します。

{ 
    GroupName, 
    EarliestCreatedDate, 
    EarliestCreatedBy, 
    LastModifiedDate, 
    LastModifiedBy, 
    TotalCount, 
    PendingCount, 
    ClosedCount 
} 

ここで、PendingCountおよびClosedCountは、ステータスがPending/Closedの各グループ内の文書の合計数です。私はこの値を抽出するために他の式を使って$ projectを使う必要があると思うが、これを把握するのに十分な集約パイプラインは本当に理解できない。

また、EarliestCreatedByおよびLastModifiedByは、それぞれEarliestCreatedDateおよびLastModifiedDateに対応するドキュメントを作成または変更したユーザーです。私が言及したように、私はこれらの値を取得することは別の複雑さの層を追加すると思います。実用的な解決策がなければ、私はこの要件を忘れてしまいます。

どのような提案やヒントも非常に高く評価されます。

答えて

0

以下の集計ステージを試すことができます。

$group

それぞれ計算EarliestCreatedDateLastModifiedDateGroupID

計算$min$maxに必要なすべてのカウントTotalCountPendingCountClosedCountpushCreatedByLastModifiedByにすべてのフィールドがEarliestCreatedByをフェッチするために、後で比較するとそれぞれについてLastModifiedByGroupID

配列オブジェクトに変換する EarliestCreatedBy$arrayElemAtから

$project

プロジェクト応答のためのすべてのフィールド

$filter

EarliestCreatedDateCreatedByLastModifiedByのデータに対する値と$map一致CreatedBy

同様の手順LastModifiedBy

db.getCollection('myCollection').aggregate(
    [{ 
     $group: { 
      _id: "$GroupID", 
      TotalCount: { 
       $sum: 1 
      }, 
      PendingCount: { 
       $sum: { 
        $cond: { 
         if: { 
          $eq: ["Status", "Pending"] 
         }, 
         then: 1, 
         else: 0 
        } 
       } 
      }, 
      ClosedCount: { 
       $sum: { 
        $cond: { 
         if: { 
          $eq: ["Status", "Closed "] 
         }, 
         then: 1, 
         else: 0 
        } 
       } 
      }, 
      GroupName: { 
       $first: "$GroupName" 
      }, 
      EarliestCreatedDate: { 
       $min: "$DateCreated" 
      }, 
      LastModifiedDate: { 
       $max: "$LastModifiedDate" 
      }, 
      CreatedByLastModifiedBy: { 
       $push: { 
        CreatedBy: "$CreatedBy", 
        LastModifiedBy: "$LastModifiedBy", 
        DateCreated: "$DateCreated", 
        LastModifiedDate: "$LastModifiedDate" 
       } 
      } 
     } 
    }, { 
     $project: { 
      _id: 0, 
      GroupName: 1, 
      EarliestCreatedDate: 1, 
      EarliestCreatedBy: { 
       $arrayElemAt: [{ 
        $map: { 
         input: { 
          $filter: { 
           input: "$CreatedByLastModifiedBy", 
           as: "CrBy", 
           cond: { 
            "$eq": ["$EarliestCreatedDate", "$$CrBy.DateCreated"] 
           } 
          } 
         }, 
         as: "EaCrBy", 
         in: { 
          "$$EaCrBy.CreatedBy" 
         } 
        } 
       }, 0] 
      }, 
      LastModifiedDate: 1, 
      LastModifiedBy: { 
       $arrayElemAt: [{ 
        $map: { 
         input: { 
          $filter: { 
           input: "$CreatedByLastModifiedBy", 
           as: "MoBy", 
           cond: { 
            "$eq": ["$LastModifiedDate", "$$MoBy.LastModifiedDate"] 
           } 
          } 
         }, 
         as: "LaMoBy", 
         in: { 
          "$$LaMoBy.LastModifiedBy" 
         } 
        } 
       }, 0] 
      }, 
      TotalCount: 1, 
      PendingCount: 1, 
      ClosedCount: 1 
     } 
    }] 
) 

を計算するためのバージョン< 3.2

$filterの更新は、あなたのバージョンでも利用できません。以下は同等です。

比較ロジックは同じで、一致しないすべてのエントリに対してfalseまたはLastModifiedByの値を持つ配列を作成します。

次のステップでは、$setDifferenceを使用して前の配列の値を配列[false]と比較し、最初のセットにのみ存在する要素を返します。

LastModifiedBy: { 
    $setDifference: [{ 
      $map: { 
       input: "$CreatedByLastModifiedBy", 
       as: "MoBy", 
       in: { 
        $cond: [{ 
          $eq: ["$LastModifiedDate", "$$MoBy.LastModifiedDate"] 
         }, 
         "$$MoBy.LastModifiedBy", 
         false 
        ] 
       } 
      } 
     }, 
     [false] 
    ] 
} 

反復の間に中間変数にアクセスするEarliestCreatedBy

+0

を算出する

{$unwind:"$LastModifiedBy"} 

同様の手順 '$$'構文オブジェクトに変更するに$project段階の後$unwindステージを追加します。 Ex'CrBy'および 'EaCrBy'。もう少し詳しくはこちらhttps://docs.mongodb.com/v3.2/reference/aggregation-variables/ – Veeram

+0

ありがとうございました。私はそれを読んで、それは私のニーズに合っていると思うが、それは私のために働いていないようだ。私は$ arrayElemAt式が私のmongo dbのバージョン3.0.12でサポートされていないと信じています。このバージョンでも同様の操作を実行する方法を知っていますか?そうでなければ、私は今のところできます。私は数ヶ月でDBを最新バージョンにアップグレードしようと考えています。 –

+0

心配はいりません。どういたしまして。あなたのバージョンのアップデートが含まれています。 – Veeram

関連する問題