sql >> データベース >  >> NoSQL >> MongoDB

レコードを月ごとにグループ化し、カウントします-Mongoose、nodeJs、mongoDb

    これは、期待される出力を返す集計クエリです。いくつかのサンプルドキュメント:

    [
      { created_at: "2020-04-04T17:02:07.832Z", productId: 1 },
      { created_at: "2020-02-01T17:02:07.832Z", productId: 1 },
      { created_at: "2020-02-19T17:02:07.832Z", productId: 1 },
      { created_at: "2019-05-22T17:02:07.832Z", productId: 1 },
      { created_at: "2020-01-15T17:02:07.832Z", productId: 1 },
      { created_at: "2020-01-30T17:02:07.832Z", productId: 2 },  // not selected
      { created_at: "2019-03-15T17:02:07.832Z", productId: 1 }   // not selected
    ]
    

    入力変数と集計:

    let TODAY = "2020-04-06T23:59:59"
    let YEAR_BEFORE = "2019-04-07T00:00:00"
    let req = { params: { productId: 1 } }
    const monthsArray = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]
    
    db.sales.aggregate( [
      { 
          $match: { 
              productId: req.params.productId, 
              created_at: { $gte: YEAR_BEFORE, $lte: TODAY }
          }
      },
      { 
          $group: {
              _id: { "year_month": { $substrCP: [ "$created_at", 0, 7 ] } }, 
              count: { $sum: 1 }
          } 
      },
      {
          $sort: { "_id.year_month": 1 }
      },
      { 
          $project: { 
              _id: 0, 
              count: 1, 
              month_year: { 
                  $concat: [ 
                     { $arrayElemAt: [ monthsArray, { $subtract: [ { $toInt: { $substrCP: [ "$_id.year_month", 5, 2 ] } }, 1 ] } ] },
                     "-", 
                     { $substrCP: [ "$_id.year_month", 0, 4 ] }
                  ] 
              }
          } 
      },
      { 
          $group: { 
              _id: null, 
              data: { $push: { k: "$month_year", v: "$count" } }
          } 
      },
      {
          $project: { 
              data: { $arrayToObject: "$data" }, 
              _id: 0 
          } 
      }
    ] )
    

    出力:

    {
            "data" : {
                    "May-2019" : 1,
                    "January-2020" : 1,
                    "February-2020" : 2,
                    "April-2020" : 1
            }
    }
    


    これが更新された集計です 。

    次の変更に注意してください。(1)新しい定数FIRST_MONTHおよびLAST_MONTH、(2)monthsArrayを変更しました 変数名をMONTHS_ARRAYに追加し、(3)3つの新しいパイプラインステージを追加しました。

    最初の2つのパイプラインステージ(新規)は、すべての月(開始日と入力日の範囲をカバー)を含むテンプレートを作成します。 3番目の新しいステージでは、テンプレートを前の集計から派生した出力データとマージします。

    const FIRST_MONTH = 1
    const LAST_MONTH = 12
    const MONTHS_ARRAY = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]
    
    let TODAY = "2020-04-06T23:59:59"
    let YEAR_BEFORE = "2019-04-07T00:00:00"
    
    db.sales.aggregate( [
      { 
          $match: { 
              productId: req.params.productId, 
              created_at: { $gte: YEAR_BEFORE, $lte: TODAY }
          }
      },
      { 
          $group: {
              _id: { "year_month": { $substrCP: [ "$created_at", 0, 7 ] } }, 
              count: { $sum: 1 }
          } 
      },
      {
          $sort: { "_id.year_month": 1 }
      },
      { 
          $project: { 
              _id: 0, 
              count: 1, 
              month_year: { 
                  $concat: [ 
                     { $arrayElemAt: [ monthsArray, { $subtract: [ { $toInt: { $substrCP: [ "$_id.year_month", 5, 2 ] } }, 1 ] } ] },
                     "-", 
                     { $substrCP: [ "$_id.year_month", 0, 4 ] }
                  ] 
              }
          } 
      },
      { 
          $group: { 
              _id: null, 
              data: { $push: { k: "$month_year", v: "$count" } }
          } 
      },
      { 
          $addFields: { 
              start_year: { $substrCP: [ YEAR_BEFORE, 0, 4 ] }, 
              end_year: { $substrCP: [ TODAY, 0, 4 ] },
              months1: { $range: [ { $toInt: { $substrCP: [ YEAR_BEFORE, 5, 2 ] } }, { $add: [ LAST_MONTH, 1 ] } ] },
              months2: { $range: [ FIRST_MONTH, { $add: [ { $toInt: { $substrCP: [ TODAY, 5, 2 ] } }, 1 ] } ] }
          } 
      },
      { 
          $addFields: { 
              template_data: { 
                  $concatArrays: [ 
                      { $map: { 
                           input: "$months1", as: "m1",
                           in: {
                               count: 0,
                               month_year: { 
                                   $concat: [ { $arrayElemAt: [ MONTHS_ARRAY, { $subtract: [ "$$m1", 1 ] } ] }, "-",  "$start_year" ] 
                               }                                            
                           }
                      } }, 
                      { $map: { 
                           input: "$months2", as: "m2",
                           in: {
                               count: 0,
                               month_year: { 
                                   $concat: [ { $arrayElemAt: [ MONTHS_ARRAY, { $subtract: [ "$$m2", 1 ] } ] }, "-",  "$end_year" ] 
                               }                                            
                           }
                      } }
                  ] 
             }
          }
      },
      { 
          $addFields: { 
              data: { 
                 $map: { 
                     input: "$template_data", as: "t",
                     in: {   
                         k: "$$t.month_year",
                         v: { 
                             $reduce: { 
                                 input: "$data", initialValue: 0, 
                                 in: {
                                     $cond: [ { $eq: [ "$$t.month_year", "$$this.k"] },
                                                  { $add: [ "$$this.v", "$$value" ] },
                                                  { $add: [ 0, "$$value" ] }
                                     ]
                                 }
                             } 
                         }
                     }
                  }
              }
          }
      },
      {
          $project: { 
              data: { $arrayToObject: "$data" }, 
              _id: 0 
          } 
      }
    ] )
    

    出力:

    {
            "data" : {
                    "April-2019" : 0,
                    "May-2019" : 1,
                    "June-2019" : 0,
                    "July-2019" : 0,
                    "August-2019" : 0,
                    "September-2019" : 0,
                    "October-2019" : 0,
                    "November-2019" : 0,
                    "December-2019" : 0,
                    "January-2020" : 1,
                    "February-2020" : 2,
                    "March-2020" : 0,
                    "April-2020" : 1
            }
    }
    


    1. 公共部門向けのAzure政府をサポートする最初のMongoDBホスティングDBaaS

    2. Stackexchange.redisにはWAITサポートがありません

    3. MongoDBで提供された配列の任意の組み合わせを含む配列フィールドのマッチング

    4. redis cluster reshard [ERR] MIGRATEの呼び出し:ERR構文エラー